6

.pemJavaで文字列(ファイル)から秘密鍵を生成したい。

private static final String test = "-----BEGIN RSA PRIVATE KEY-----\n" +
         "MIIEpAIBAAKCAQEAvcCH8WsT1xyrZqq684VPJzOF3hN5DNbowZ96Ie//PN0BtRW2\n" +
// and so on
         "-----END RSA PRIVATE KEY-----";

try {
    String privKeyPEM = test.replace("-----BEGIN RSA PRIVATE KEY-----\n", "");
    privKeyPEM = privKeyPEM.replace("-----END RSA PRIVATE KEY-----", "");

    byte [] encoded = Base64.decode(privKeyPEM);

    PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);
    KeyFactory kf = KeyFactory.getInstance("RSA");
    PrivateKey privKey = kf.generatePrivate(keySpec);
}
catch (Exception e) {
    e.printStackTrace();
}

最後の行 (generatePrivate 関数) は、この例外をスローしています:

java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException : algid parse error, not a sequence
    at sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(Unknown Source)
    at java.security.KeyFactory.generatePrivate(Unknown Source)
    at Test.main(Test.java:52)
Caused by: java.security.InvalidKeyException: IOException : algid parse error, not a sequence
    at sun.security.pkcs.PKCS8Key.decode(Unknown Source)
    at sun.security.pkcs.PKCS8Key.decode(Unknown Source)
    at sun.security.rsa.RSAPrivateCrtKeyImpl.<init>(Unknown Source)
    at sun.security.rsa.RSAPrivateCrtKeyImpl.newKey(Unknown Source)
    at sun.security.rsa.RSAKeyFactory.generatePrivate(Unknown Source)
    ... 3 more

秘密鍵をファイルの値に変更する.derと正常に機能しますが、ファイルから秘密鍵ファイルを生成する必要があり.pemます。

文字列として印刷されたバイトのスクリーンショット (\n でハードコードされ、\n なしでハードコードされたもの) と、ファイルからのスクリーンショットを添付しました。

拡大画像

出力

奇妙なことに、ファイルからの出力は文字列からの出力とは異なります。

ファイルを Base64 でエンコードしようとすると.der、結果がファイル内の文字列とは異なり.pemます。どうしてこんなことに?

4

1 に答える 1

1

最後の行が例外をスローしているとあなたは言います、つまり

PrivateKey privKey = kf.generatePrivate(keySpec);

上記の行は、キースペックが正しく設定されている場合に機能します。つまり、

PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);

実際の問題は、エンコードされたバイト配列にあります。後で System.out を実行byte [] encoded = Base64.decode(privKeyPEM);して、出力が何であるかを確認しましたか。

メッセージが MIME 形式の場合、特定の文字の後に改行と改行の組み合わせが追加されるため、文字列が電子メール システムや使用している場所では長すぎないことを理解しています。

最後の文字列テストでは、使用する元のテキストに「\n」が含まれています。下の行の他のテキストを削除しましたが、

String privKeyPEM = test.replace("-----BEGIN RSA PRIVATE KEY-----\n", "");
    privKeyPEM = privKeyPEM.replace("-----END RSA PRIVATE KEY-----", "");

しかし、文字列を見て、

"MIIEpAIBAAKCAQEAvcCH8WsT1xyrZqq684VPJzOF3hN5DNbowZ96Ie//PN0BtRW2\n" +
// and so on
         "-----END RSA PRIVATE KEY-----";

「\n」が残っている可能性があり、キースペックを生成するときに不要な文字が発生する可能性があります。さらに System.out を試して、エンコードされたバイト配列がどのようなものかを確認し、その前に String privKeyPEM をチェックして、余分な文字が残っていないかどうかを確認します。

これが役立つことを願っています。

于 2013-08-22T05:38:14.597 に答える