3

私は 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 バイトのバイト配列ですが、バウンシー キャッスルを使用して JavaME でエンコードされた同じキー 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 のあいまいさが本当に際立つポイントの 1 つだと思います)

再びあなたの応答に感謝します.あなたは私を正しい軌道に乗せました.

4

1 に答える 1

11

DER エンコーディングは、エンコーディングの単なる標準です。キーが DER でエンコードされていると言うのは、XML でエンコードされていると言うのと同じです。キーをデコードできるようにするには、DER/XML でエンコードされている方法に同意する必要があります。

この場合RSAPublicKeyStructure.getEncoded()、キーは ASN.1 の DER エンコードとして返されますRSAPublicKey

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

一方X509EncodedKeySpec、 は ASN.1 の DER エンコードが渡されることを期待していますPublicKeyInfo

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();
于 2011-01-19T19:42:55.697 に答える