传输 RSA 公钥、javaME、充气城堡时出现问题

发布于 2024-10-12 16:43:53 字数 2652 浏览 9 评论 0原文

我正在致力于将实例消息应用程序从 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(使用getencoded()函数)的DER编码密钥是一个字节数组,长度为162字节,而使用bouncy castle在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?(我猜这是 bouncy 城堡 API 的晦涩之处真正闪耀的地方之一)

再次感谢您的回复,您给了我很大的帮助。您让我上了正确的轨道。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

昵称有卵用 2024-10-19 16:43:53

DER 编码只是一种编码标准。说密钥是 DER 编码的就相当于说它是 XML 编码的:您需要就其 DER-/XML 编码方式达成一致才能对其进行解码。

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

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

另一个上的 X509EncodedKeySpec hand 希望获得 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();

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();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文