13

以下の形式で文字列を送信します。

-----BEGIN RSA PUBLIC KEY-----
MIGHAoGBANAahj75ZIz9nXqW2H83nGcUao4wNyYZ9Z1kiNTUYQl7ob/RBmDzs5rY
mUahXAg0qyS7+a55eU/csShf5ATGzAXv+DDPcz8HrSTcHMEFpuyYooX6PrIZ07Ma
XtsJ2J4mhlySI5uOZVRDoaFY53MPQx5gud2quDz759IN/0gnDEEVAgED
-----END RSA PUBLIC KEY-----

この文字列からPublicKeyオブジェクトを作成するにはどうすればよいですか?以下を試してみましたヘッダーとフッターを削除し、base64でバッファをデコードします

public static PublicKey getFromString(String keystr) throws Exception
  {
  //String S1= asciiToHex(keystr);
   byte[] keyBytes = new sun.misc.BASE64Decoder().decodeBuffer(keystr);
   X509EncodedKeySpec spec =
       new X509EncodedKeySpec(keyBytes);
     KeyFactory kf = KeyFactory.getInstance("RSA");
     return kf.generatePublic(spec);

  }

これは、無効なキー形式として失敗するか、以下のエラーが発生します

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)
 at PublicKeyReader.getFromString(PublicKeyReader.java:30)
 at Tst.main(Tst.java:36)

キーはopenSSLのAPIを介して生成されていますPEM_write_bio_RSAPublicKey(bio, rsa);

4

3 に答える 3

9

PEM_write_bio_RSAPublicKeyキーモジュラスと公開指数のみを呼び出すことにより、出力 PEM データにエンコードされます。ただし、次のX509EncodedKeySpecASN.1 キー形式が期待されます。

 SubjectPublicKeyInfo ::= SEQUENCE {
   algorithm AlgorithmIdentifier,
   subjectPublicKey BIT STRING }

PEM_write_bio_PUBKEYSubjectPublicKeyInfo 構造を使用して公開鍵をエンコードする関数を使用する必要があります。X509EncodedKeySpec

キーをデコードする別の解決策。残念ながら、標準の JDK API だけでできるとは思いませんが、Bouncycastleライブラリでできると思います。

import org.bouncycastle.asn1.*;
import org.bouncycastle.asn1.x509.RSAPublicKeyStructure;

public static PublicKey getFromString(String keystr) throws Exception
{
  //String S1= asciiToHex(keystr);
   byte[] keyBytes = new sun.misc.BASE64Decoder().decodeBuffer(keystr);
   ASN1InputStream in = new ASN1InputStream(keyBytes);
   DERObject obj = in.readObject();
   RSAPublicKeyStructure pStruct = RSAPublicKeyStructure.getInstance(obj);
   RSAPublicKeySpec spec = new RSAPublicKeySpec(pStrcut.getModulus(), pStruct.getPublicExponent());
   KeyFactory kf = KeyFactory.getInstance("RSA");
   return kf.generatePublic(spec);
}
于 2010-10-27T12:55:58.720 に答える
5

BouncyCastle の PEMReader がこれを行います。

String pemKey = "-----BEGIN RSA PUBLIC KEY-----\n"
            + "MIGHAoGBANAahj75ZIz9nXqW2H83nGcUao4wNyYZ9Z1kiNTUYQl7ob/RBmDzs5rY\n"
            + "mUahXAg0qyS7+a55eU/csShf5ATGzAXv+DDPcz8HrSTcHMEFpuyYooX6PrIZ07Ma\n"
            + "XtsJ2J4mhlySI5uOZVRDoaFY53MPQx5gud2quDz759IN/0gnDEEVAgED\n"
            + "-----END RSA PUBLIC KEY-----\n";
PEMReader pemReader = new PEMReader(new StringReader(pemKey));
RSAPublicKey rsaPubKey = (RSAPublicKey) pemReader.readObject();
System.out.println("Public key: "+rsaPubKey);

Security.addProvider(new BouncyCastleProvider());(前にどこかが必要になる場合があることに注意してください。)

于 2010-11-03T16:18:38.220 に答える