Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
625 views
in Technique[技术] by (71.8m points)

encryption - Problem transmiting a RSA public key, javaME , bouncy castle

I'm working on the porting of an instance messaging application from Java to JavaME ,that also implements cryptography. The problem is that I want to send my public key to the server. The desktop client has this code for this job:

byte[] encoded_public_key=publick_key.getEncoded();

And the server has this code to retrieve the key:

EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(encoded_public_key);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey puKey = keyFactory.generatePublic(publicKeySpec);

Now I've looked the API for the getEncoded and it says that it returns the DER-encoded form of the key as a byte array (http://www.docjar.com/docs/api/sun/s...tml#getEncoded)

My implementation for that in JavaME was this:

RSAPublicKeyStructure public_key_JAVAME=new RSAPublicKeyStructure(modulus,exponent);
byte[] DER_encoded_public_key_JAVAME=public_key_JAVAME.getDEREncoded();

//the getEncoded functions returns exact the same byte array.

However when I try to retrieve the JavaME created DER encoded key with the server code ,in other words when I try this:

EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(DER_encoded_public_key_JAVAME);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey puKey = keyFactory.generatePublic(publicKeySpec);

I get

java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException: algid parse error, not a sequence
at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:188)
at java.security.KeyFactory.generatePublic(KeyFactory.java:304)

Caused by: java.security.InvalidKeyException: IOException: algid parse error, not a sequence
at sun.security.x509.X509Key.decode(X509Key.java:380)
at sun.security.x509.X509Key.decode(X509Key.java:386)
at sun.security.rsa.RSAPublicKeyImpl.<init>(RSAPublicKeyImpl.java:66)
at sun.security.rsa.RSAKeyFactory.generatePublic(RSAKeyFactory.java:281)
at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:184)

Interesting point : The DER encoded key from the normal Java (using the getencoded() function) is a byte array is 162 bytes long while the SAME key DER encoded in JavaME using bouncy castle is 140 bytes long. Shouldn't these 2 DER encoded key be of the same lenght?I mean it's the same key in DER encoded format so they should be the same.

What am I doing wrong?


True I didn't notice that.Problem is do you know how to create a subjectPublickeyInfo object from a PublicKey in bouncyCastle? I've tried:

ByteArrayInputStream bIn = new ByteArrayInputStream(RSApublickey.toString().getbytes()); SubjectPublicKeyInfo info = new SubjectPublicKeyInfo((ASN1Sequence)new ASN1InputStream(bIn).readObject());

But it didn't work. I also tried :

ByteArrayInputStream(RSApublicKeyStructure.getEncoded()); SubjectPublicKeyInfo info = new SubjectPublicKeyInfo((ASN1Sequence)new ASN1InputStream(bIn).readObject());

Actually I did expect that not to work , but well I had to try it . So how can I create a Subjectpublickeyinfo from RSAkeyparameters?( This is one of the points where the obscurity of bouncy's castle API really shines I guess)

Again thank you for your response you've been of great help.You've put me on the right track.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

DER-encoding is just a standard for encoding. Saying that a key is DER-encoded is equivalent to saying it is XML-encoded: you need to agree on how it is DER-/XML-encoded to be able to decode it.

In this case your RSAPublicKeyStructure.getEncoded() returns the key as the DER-encoding of an ASN.1 RSAPublicKey:

RSAPublicKey ::= SEQUENCE {
  modulus INTEGER, -- n
  publicExponent INTEGER -- e 
}

The X509EncodedKeySpec on the other hand expects to be handed the DER-encoding of an ASN.1 PublicKeyInfo:

PublicKeyInfo ::= SEQUENCE {
  algorithm AlgorithmIdentifier,
  PublicKey BIT STRING
}

To create a PublicKeyInfo using BouncyCastle do this (courtesy of GregS):

RSAPublicKeyStructure rsaPublicKey = /* ... */
AlgorithmIdentifier rsaEncryption = new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE); 
SubjectPublicKeyInfo publicKeyInfo = new SubjectPublicKeyInfo(rsaEncryption, rsaPublicKey);
byte[] encodedPublicKeyInfo = publicKeyInfo.getEncoded();

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...