2
$\begingroup$

To write a CTF challenge, I want to create an RSA key pair of size 228-bit. I want the keys exactly in the same format as OpenSSL-generated keys. But, OpenSSL is not supporting less than 512-bit long keys. What could be a solution?

$\endgroup$

2 Answers 2

2
$\begingroup$

In the end you'll have to program it I suppose, here's a small Java application that creates a PEM encoded RSA PRIVATE KEY (unencrypted PKCS#1 structure) and PUBLIC KEY (X.509 SubjectPublicKeyInfo).

Obviously it is build on top of the Bouncy Castle provider for Java / JCA and the PemWriter from the "lightweight" API that is part of the provider package.

package com.stackexchange.crypto;

import java.io.FileWriter;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.Security;

import org.bouncycastle.asn1.ASN1Object;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemWriter;

public class ShortRsaKeyPair {

    public static void main(String[] args) throws Exception{
        Security.addProvider(new BouncyCastleProvider()); 
        KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "BC");
        kpg.initialize(228);
        KeyPair kp = kpg.generateKeyPair();
        
        PrivateKeyInfo privKeyInfo = PrivateKeyInfo.getInstance(ASN1Sequence.getInstance(kp.getPrivate().getEncoded()));
        ASN1Object pkcs1Object = (ASN1Object) privKeyInfo.parsePrivateKey(); 
        try (PemWriter pemWriter = new PemWriter(new FileWriter("privkey.pem"))) {
            pemWriter.writeObject(new PemObject("RSA PRIVATE KEY", pkcs1Object.getEncoded("DER")));
        }
 
        // not needed, you can also generate it from the private key using "openssl rsa -pubout"
        try (PemWriter pemWriter = new PemWriter(new FileWriter("pubkey.pem"))) {
            pemWriter.writeObject(new PemObject("PUBLIC KEY", kp.getPublic().getEncoded()));
        }
    }
}

You can check the result using:

openssl rsa -pubin -in pubkey.pem -text
openssl rsa -in privkey.pem -text
$\endgroup$
2
$\begingroup$

The format of RSA private keys is described in PKCS#1 V2.2 appendix A.1.2. OpenSSL can be told to output a key in that format with PEM formatting over that, so that the resulting data is text; that's practice for RSA private keys when not encrypted.

The code for this given $(p,q,e)$ is one page of Python (with no assurance of correctness) in this Try It Online!

One can parse the result with Lapo Luchini's ASN.1 JavaScript decoder.

With the private key in private.pem, OpenSSL can generate the public key with

openssl rsa -in private.pem -outform PEM -pubout -out public.pem

One can also parse the result with said ASN.1 JavaScript decoder.

$\endgroup$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.