Can org.bouncycastle.openssl.PEMReader read java.security.PrivateKey?

10,256

A file can contain only a private key, and it can be encrypted or clear text. OpenSSL does this all the time.

I reviewed the code for PEMReader, however, and it looks like it will return a KeyPair from an RSA private key (the private key file contains all the necessary information for the corresponding public key). It looks like it will never return simply a PrivateKey from readObject().

Here's an unencrypted 1024 RSA private key from OpenSSL.

-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQC/oBTZGo0cgHHdZD8LgDpUVOPjsI58PrTJPtrlVT7kyznmzFEt
TW9cqxlw6EOo09tTTrjikLDA2M5xzejbLGPb8sa7AzVhuHkChgGh9eZmphsnvq1W
LjuXCk5yWOR9ziaBKKFeNXOsdvDp3eMDM+wz3vzn1wrGrg00jMvKP5kcpwIDAQAB
AoGBAI9oJ/IKEszfu1cqLJxYzE5McXf2q8uDyhxJs9upHjZveNem1KGIr+y0B4gd
6nSwiBUidu7nxb+tAWLd7IQKBnhKC3AtGNT7qTwnXelKsJhaok2+kEEuzjQYnmsP
AreEsAi/FlHj/kAyjGBoQ4QLrx1sp2cDcBTP78PeJfZvm/RxAkEA7zVuumjrz3ui
zmBzQI1pwD9F0REyE5zJfgUz5iDQbK2RRPhcQ9LCZdEJRU0vdWTBmmgadYwpg0uG
hYFwCy7PWwJBAM0Tk+pMRwke0m4oiI4mKh0u4enHXE2RFMUtTMjGILHt8+m4Q7rd
KGfO9/ylK82LhbT0Z/BeszbnneaAefkxFaUCQQDephVSXKZgkOuQvCWKSBXOYxZQ
6nh52M2TBrSv1ospHMTCNYlrd5iJvG+smZM66XVqistV7ggVtQ6Y5Umsnv1RAkBW
l/K4V1cTcdFXNIRcyZ60zewUw9qk4iMME1G94XNCzoBU6zqmN+Zs1wb9xlzVoRln
TGBrLgGsqGaTQyK9500FAkBuKohFvOgFHSKOskiVu/swByWZANEZsoEPUx7V6vXH
Tk+qftY64tt4AazHPVyVtsj1oqOv3zbulfnotFvU1nmp
-----END RSA PRIVATE KEY-----

Here's the corresponding public key:

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC/oBTZGo0cgHHdZD8LgDpUVOPj
sI58PrTJPtrlVT7kyznmzFEtTW9cqxlw6EOo09tTTrjikLDA2M5xzejbLGPb8sa7
AzVhuHkChgGh9eZmphsnvq1WLjuXCk5yWOR9ziaBKKFeNXOsdvDp3eMDM+wz3vzn
1wrGrg00jMvKP5kcpwIDAQAB
-----END PUBLIC KEY-----

A KeyStore is meant to be used to carry public, private, and symmetric keys in a Java application. Most Java applications store private keys in a PKCS #8 encoding (which is not the same as the OpenSSL format), and public keys are represented with a SubjectPublicKeyInfo structure (which is the same as OpenSSL).

Share:
10,256
Martin Ždila
Author by

Martin Ždila

https://linkedin.com/in/zdila/

Updated on June 17, 2022

Comments

  • Martin Ždila
    Martin Ždila almost 2 years

    I have following code:

    PrivateKey key = null;
    X509Certificate cert = null;
    KeyPair keyPair = null;
    
    final Reader reader = new StringReader(pem);
    try {
        final PEMReader pemReader = new PEMReader(reader, new PasswordFinder() {
            @Override
            public char[] getPassword() {
                return password == null ? null : password.toCharArray();
            }
        });
    
        Object obj;
        while ((obj = pemReader.readObject()) != null) {
            if (obj instanceof X509Certificate) {
                cert = (X509Certificate) obj;
            } else if (obj instanceof PrivateKey) {
                key = (PrivateKey) obj;
            } else if (obj instanceof KeyPair) {
                keyPair = (KeyPair) obj;
            }
        }
    } finally {
        reader.close();
    }
    

    Will it ever read PrivateKey? In other words, can any PEM file contain pure private key only? If yes, could you provide me a sample PEM file?

    Thanks in advace.

  • Martin Ždila
    Martin Ždila over 12 years
    Thanks for answer. Your sample of private key contains also public key and therefore it is a KeyPair. You can extract a public key with: openssl pkey -inform PEM -pubout -outform PEM. I was wondering if there can be a PEM with just a pure private key, with no information about public key.
  • brady
    brady over 12 years
    @Martin Actually, what my sample contains is an RSAPrivateKey, as defined PKCS #1. As I stated, it does contain the public exponent (along with the Chinese Remainder Theorem values), to facilitate recovery of the public key. Any private key that can be read by PEMReader (or the OpenSSL utilities) must be in this standard format, although this can be enclosed in a PKCS #8 or PEM wrapper. Some implementations of SSH2 are unusual in that they don't use a PKCS #1 key. PEMReader will never return a PrivateKey; it will raise an exception if a private key is not in PKCS #1 format.