Skip to Main Content

Java Security

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Interested in getting your voice heard by members of the Developer Marketing team at Oracle? Check out this post for AppDev or this post for AI focus group information.

Reading PKCS#1 private key from file

843811Feb 4 2008 — edited Feb 7 2008
Hi I'm pretty new to JCE/JSSE. I'd like to read in a PKCS#1 formatted private key from a file. The goal of this is to extract the modulus to validate against a public key (verify they are a key pair).

To accomplish this I can read in the privatekey into a byte array and I tried to create a "RSAPrivateCrtKeySpec" object but the constructor requires many of values I don't directly have (unless i can somehow extract them from the file/byteArray)

Is there a way to do this without relying on external calls to openssl to extract portions of the key from the file?


Thanks for your help,

Chris

Comments

843811
either parse the big integers directly from pkcs#1 and use the RSAPrivateKeySpec or RSAPrivateCrtKeySpec constructors, or better yet make the pkcs#1 file into a pkcs#8 file and use the PKCS8EncodedKeySpec. The KeySpec can then be used with the KeyFactory class to generate the Public and PrivateKey objects.
843811
Hi, thats what I assumed, but how do you read the big ints from the key file? (sorry if this is obvious... also if the size of the key changes, how will my reads remain accurate?)

For example my key could look like:
-----BEGIN RSA PRIVATE KEY-----
MIIBOwIBAAJBALf+EfAvqNlTrTwPy1BrqpXkX21KUu2My/JVupfDHIQ84e+uNUYm
2UrcPVYjg8+C9M5dZU83s8jvu/cwOw14MyECAwEAAQJALTVhZPng7B1yWGqtE0KR
NKlbhTgY7kOFLTNBWN7ZF+iPENnJLIjze8zfkMsQsTaD2Sa8NCigBT1ClZDBHNLT
QQIhAN4Jt6r6Hf81MRSaHKVogkUkIKsyMQ3jzxT9xKF0SkPZAiEA1CKdbva93MJo
KRr9SmgYqKziAmLFj2bpXOz/tSvuhIkCIQCa4aZnsq7H/b+twk6nJv5v4mKTaKCF
MtqZpubJRMglCQIgNmEpOmjGAvFTAjaI96n3qEWpKjNnsXsQF2Ipqqe4XQECIQCO
19jR6lk+DIrjKl76tBHsuH5fIoJhvE0Nk1OdwLlLPA==
-----END RSA PRIVATE KEY-----

How can I extract:
modulus - the modulus n
publicExponent - the public exponent e
privateExponent - the private exponent d
primeP - the prime factor p of n
primeQ - the prime factor q of n

I assume that when you state "make the pkcs#1 file into a pkcs#8 file " this involves using an external tool like openssl, which won't work for me as I need to do this in java (JCE/JSSE).

Thanks
843811
chatko wrote:
Hi, thats what I assumed, but how do you read the big ints from the key file? (sorry if this is obvious... also if the size of the key changes, how will my reads remain accurate?)

For example my key could look like:
-----BEGIN RSA PRIVATE KEY-----
MIIBOwIBAAJBALf+EfAvqNlTrTwPy1BrqpXkX21KUu2My/JVupfDHIQ84e+uNUYm
2UrcPVYjg8+C9M5dZU83s8jvu/cwOw14MyECAwEAAQJALTVhZPng7B1yWGqtE0KR
NKlbhTgY7kOFLTNBWN7ZF+iPENnJLIjze8zfkMsQsTaD2Sa8NCigBT1ClZDBHNLT
QQIhAN4Jt6r6Hf81MRSaHKVogkUkIKsyMQ3jzxT9xKF0SkPZAiEA1CKdbva93MJo
KRr9SmgYqKziAmLFj2bpXOz/tSvuhIkCIQCa4aZnsq7H/b+twk6nJv5v4mKTaKCF
MtqZpubJRMglCQIgNmEpOmjGAvFTAjaI96n3qEWpKjNnsXsQF2Ipqqe4XQECIQCO
19jR6lk+DIrjKl76tBHsuH5fIoJhvE0Nk1OdwLlLPA==
-----END RSA PRIVATE KEY-----

How can I extract:
modulus - the modulus n
publicExponent - the public exponent e
privateExponent - the private exponent d
primeP - the prime factor p of n
primeQ - the prime factor q of n
Well, naturally there is more than one way to extract the quantities. Here is a complete example that uses two libraries, the jakarta commons codec (for base64 decoding) and the bouncycastle library.
import java.security.KeyFactory;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.RSAPrivateKeySpec;

import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.pkcs.RSAPrivateKeyStructure;

public class PrivateKeyParseToy
{
    public static void main(String[] args) throws Exception
    {
        String b64encoded = "MIIBOwIBAAJBALf+EfAvqNlTrTwPy1BrqpXkX21KUu2My/JVupfDHIQ84e+uNUYm"
                + "2UrcPVYjg8+C9M5dZU83s8jvu/cwOw14MyECAwEAAQJALTVhZPng7B1yWGqtE0KR"
                + "NKlbhTgY7kOFLTNBWN7ZF+iPENnJLIjze8zfkMsQsTaD2Sa8NCigBT1ClZDBHNLT"
                + "QQIhAN4Jt6r6Hf81MRSaHKVogkUkIKsyMQ3jzxT9xKF0SkPZAiEA1CKdbva93MJo"
                + "KRr9SmgYqKziAmLFj2bpXOz/tSvuhIkCIQCa4aZnsq7H/b+twk6nJv5v4mKTaKCF"
                + "MtqZpubJRMglCQIgNmEpOmjGAvFTAjaI96n3qEWpKjNnsXsQF2Ipqqe4XQECIQCO"
                + "19jR6lk+DIrjKl76tBHsuH5fIoJhvE0Nk1OdwLlLPA==";
        byte [] asn1PrivateKeyBytes = org.apache.commons.codec.binary.Base64.decodeBase64(b64encoded.getBytes("US-ASCII"));
        RSAPrivateKeyStructure asn1PrivKey = new RSAPrivateKeyStructure((ASN1Sequence) ASN1Sequence.fromByteArray(asn1PrivateKeyBytes));
        RSAPrivateKeySpec rsaPrivKeySpec = new RSAPrivateKeySpec(asn1PrivKey.getModulus(), asn1PrivKey.getPrivateExponent());
        KeyFactory kf = KeyFactory.getInstance("RSA");
        RSAPrivateKey privKey = (RSAPrivateKey) kf.generatePrivate(rsaPrivKeySpec);
        System.out.println(privKey.getPrivateExponent());
    }
}
I assume that when you state "make the pkcs#1 file into a pkcs#8 file " this involves using an external tool like openssl, which won't work for me as I need to do this in java (JCE/JSSE).
Yes. My thought was that you could change the process upstream from you that is generating the PKCS#1 file and instead have it generate a PKCS#8 file. As an alternative, it would not be hard to "glue" the necessary bytes onto the front of the PKCS#1 file to create the PKCS#8 file.
843811
Hi Thanks for the example, I guess the critical part is

RSAPrivateKeyStructure asn1PrivKey = new RSAPrivateKeyStructure((ASN1Sequence) ASN1Sequence.fromByteArray(asn1PrivateKeyBytes));

Unfortunately, I'm not permitted to use BouncyCastle libs. Am I correct is assuming this will be difficult to do using just JCE classes?


Alternatively, apache publishes this approach using openssl:

$ openssl x509 -noout -modulus -in server.crt | openssl md5
$ openssl rsa -noout -modulus -in server.key | openssl md5

Compare these two values and I should know if the private key and public key in cert is a pair which solves my original problem, but does use an external call.

Again, thanks for you time
843811
chatko wrote:
Hi Thanks for the example, I guess the critical part is

RSAPrivateKeyStructure asn1PrivKey = new RSAPrivateKeyStructure((ASN1Sequence) ASN1Sequence.fromByteArray(asn1PrivateKeyBytes));

Unfortunately, I'm not permitted to use BouncyCastle libs. Am I correct is assuming this will be difficult to do using just JCE classes?
No, it will be harder to do it without BC but not that hard. You must figure out how to parse ASN.1 DER Sequences and DER integers. In this case it is rather easier than in general. I recommend the "Layman's Guide To ..." at ftp://ftp.rsa.com/pub/pkcs/ascii/layman.asc.

>
Alternatively, apache publishes this approach using openssl:

$ openssl x509 -noout -modulus -in server.crt | openssl md5
$ openssl rsa -noout -modulus -in server.key | openssl md5

Compare these two values and I should know if the private key and public key in cert is a pair which solves my original problem, but does use an external call.

Again, thanks for you time
1 - 5
Locked Post
New comments cannot be posted to this locked post.

Post Details

Locked on Mar 6 2008
Added on Feb 4 2008
5 comments
8,177 views