传输RSA公钥,java,充气城堡的问题

时间:2011-01-19 19:22:53

标签: encryption java-me bouncycastle

我正在努力将实例消息传递应用程序从Java移植到JavaME,它还实现了加密。问题是我想将我的公钥发送到服务器。桌面客户端具有此代码的代码:

byte[] encoded_public_key=publick_key.getEncoded();

服务器有这个代码来检索密钥:

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

现在我看了getEncoded的API,它说它将字符串的DER编码形式的字符串返回(http://www.docjar.com/docs/api/sun/s。 ..tml#的getEncoded)

我在JavaME中的实现是这样的:

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.

然而,当我尝试使用服务器代码检索JavaME创建的DER编码密钥时,换句话说,当我尝试这样做时:

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

我得到了

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)

有趣的是:来自普通Java的DER编码密钥(使用getencoded()函数)是一个162字节长的字节数组,而使用充气城堡在JavaME中编码的SAME密钥DER长140字节。这些2 DER编码密钥不应该具有相同的长度吗?我的意思是它与DER编码格式的密钥相同,所以它们应该是相同的。

我做错了什么?


是的,我没注意到。问题是你知道如何从bouncyCastle中的PublicKey创建一个subjectPublickeyInfo对象吗?我试过了:

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

但它没有用。我也尝试过:

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

实际上我确实希望不能工作,但我必须尝试一下。那么我怎样才能从RSAkeyparameters创建一个Subjectpublickeyinfo?(这是我觉得有弹性的城堡API默默无闻的点之一)

再次感谢您的回复,您的帮助很大。您已经把我放在了正确的轨道上。

1 个答案:

答案 0 :(得分:10)

DER编码只是编码的标准。说一个密钥是DER编码的,就等于说它是XML编码的:你需要同意如何进行DER- / XML编码才能解码它。

在这种情况下,您的RSAPublicKeyStructure.getEncoded()会将密钥作为ASN.1 RSAPublicKey的DER编码返回:

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

另一方面,X509EncodedKeySpec期望获得ASN.1 PublicKeyInfo的DER编码:

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

使用BouncyCastle创建PublicKeyInfo执行此操作(由GregS提供):

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