Jenananthan
Jenananthan

Reputation: 1401

Read RSA private key of format PKCS1 in JAVA

Is it possible to read the RSA private key of format PKCS1 in JAVA without converting to PKCS8? if yes, sample code is appreciated.

-----BEGIN RSA PRIVATE KEY-----
 BASE64 ENCODED DATA
-----END RSA PRIVATE KEY-----

Upvotes: 19

Views: 24721

Answers (2)

Ahmed Ashour
Ahmed Ashour

Reputation: 5549

As hinted here, there is a solution without BouncyCastle.

import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;

public class Pkcs1ToPkcs8 {
  private static final String PRIVATE_KEY = """
      -----BEGIN RSA PRIVATE KEY-----
      MIIEogIBAAKCAQEAkiAWsNL5sQqkDi04soEEOGiZQ7LlB91Z3jh1uHFByXXixHVC
      VwuahgAWxJ345G6AZVqgPxLnopPh513kXTPWRMggC6HszU+jQp3fkNo7OnzMhQcP
      ...
      -----END RSA PRIVATE KEY-----
      """;

  public static void main(String[] args) throws Exception {
    var pem = PRIVATE_KEY
        .replaceAll("-----.+KEY-----", "")
        .replaceAll("\\s+", "");

    var bytes = Base64.getDecoder().decode(pem);
    bytes = buildPkcs8KeyFromPkcs1Key(bytes);
    var keyFactory = KeyFactory.getInstance("RSA");
    var keySpec = new PKCS8EncodedKeySpec(bytes);
    var privateKey = (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
    System.out.println(privateKey);
  }

  private static byte[] buildPkcs8KeyFromPkcs1Key(byte[] innerKey) {
    var result = new byte[innerKey.length + 26];
    System.arraycopy(Base64.getDecoder().decode("MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKY="), 0, result, 0, 26);
    System.arraycopy(BigInteger.valueOf(result.length - 4).toByteArray(), 0, result, 2, 2);
    System.arraycopy(BigInteger.valueOf(innerKey.length).toByteArray(), 0, result, 24, 2);
    System.arraycopy(innerKey, 0, result, 26, innerKey.length);
    return result;
  }
}

Upvotes: 1

pedrofb
pedrofb

Reputation: 39241

Java does not come with out-of-the-box support for PKCS1 keys. You can however use Bouncycastle

PEMParser pemParser = new PEMParser(new FileReader(privateKeyFile));
JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
Object object = pemParser.readObject();
KeyPair kp = converter.getKeyPair((PEMKeyPair) object);
PrivateKey privateKey = kp.getPrivate();

Upvotes: 32

Related Questions