我正在将实例消息传递应用程序从 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 字节,而使用 bouncy castle 的 JavaME 中编码的 SAME 密钥 DER 长度为 140 字节。这两个 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 呢?(我猜这是 bouncy 的城堡 API 的默默无闻的真正亮点之一)
再次感谢您的回复,您提供了很大的帮助。您让我走上了正确的道路。