Encryption 传输RSA公钥、javaME、bouncy castle时出现问题

Encryption 传输RSA公钥、javaME、bouncy castle时出现问题,encryption,java-me,bouncycastle,Encryption,Java Me,Bouncycastle,我正在将一个实例消息传递应用程序从Java移植到JavaME,它也实现了加密。问题是我想将公钥发送到服务器。桌面客户端对此作业具有以下代码: byte[] encoded_public_key=publick_key.getEncoded(); 服务器有以下代码来检索密钥: EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(encoded_public_key); KeyFactory keyFactory = KeyFactory.g

我正在将一个实例消息传递应用程序从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解析错误,不是序列
位于sun.security.rsa.RSAKeyFactory.EngineeGeneratePublic(RSAKeyFactory.java:188)
位于java.security.KeyFactory.generatePublic(KeyFactory.java:304)
原因:java.security.InvalidKeyException:IOException:algid解析错误,不是序列
位于sun.security.x509.X509Key.decode(X509Key.java:380)
位于sun.security.x509.X509Key.decode(X509Key.java:386)
位于sun.security.rsa.rsaplickeyimpl.(rsaplickeyimpl.java:66)
位于sun.security.rsa.RSAKeyFactory.generatePublic(RSAKeyFactory.java:281)
位于sun.security.rsa.RSAKeyFactory.EngineeGeneratePublic(RSAKeyFactory.java:184)
有趣的是:普通Java(使用getencoded()函数)中的DER编码键是一个字节数组,长度为162字节,而使用bouncy castle在JavaME中编码的相同键DER长度为140字节。这两个DER编码的密钥不应该具有相同的长度吗?我的意思是,它是DER编码格式的相同密钥,所以它们应该是相同的

我做错了什么


是的,我并没有注意到。问题是你们知道如何从bouncyCastle中的公钥创建subjectPublickeyInfo对象吗?我试过:

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

但它不起作用。我还尝试:

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

事实上,我确实认为这不管用,但我不得不尝试一下。那么,如何从RSAkeyparameters创建Subjectpublickeyinfo呢?(我想这是bouncy的castle API的晦涩之处之一)


再次感谢你的回复,你帮了我很大的忙,你让我走上了正确的道路

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创建公钥信息,请执行以下操作(由提供):


我不知道我不回答评论是否正确,但我的答案太难理解,因为代码原因,作为评论sample@user581979您可以更新您的问题。看到这个答案可能会让人困惑。根据rfc3279#2.3.1,RSA的算法标识符必须将参数设置为显式ASN.1 NULL,而不是像Java
NULL
那样忽略--使用
DERNull.INSTANCE
instead@dave_thompson_085谢谢我犯了那个错误(把编程语言null和ASN.1 null混在一起)太多次了。
PublicKeyInfo ::= SEQUENCE {
  algorithm AlgorithmIdentifier,
  PublicKey BIT STRING
}
RSAPublicKeyStructure rsaPublicKey = /* ... */
AlgorithmIdentifier rsaEncryption = new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE); 
SubjectPublicKeyInfo publicKeyInfo = new SubjectPublicKeyInfo(rsaEncryption, rsaPublicKey);
byte[] encodedPublicKeyInfo = publicKeyInfo.getEncoded();