1

DKIM for JavaMailを使用して、 DKIM で送信メールに署名しています。
私のプライベート DKIM キーはopendkim-genkey -s default -d example.com次のように生成されます。

-----BEGIN RSA PRIVATE KEY-----
ABCCXQ...[long string]...SdQaZw9
-----END RSA PRIVATE KEY-----

JavaMail ライブラリの DKIM には、readme ファイルに記載されているように、DER 形式の秘密 DKIM キーが必要です。

JavaMail の DKIM には DER 形式の秘密鍵が必要です。openssl を使用して PEM キーを変換できます。

openssl pkcs8 -topk8 -nocrypt -in private.key.pem -out private.key.der -outform der

openssl を使用してキーを DER 形式に変換する必要がないようにする方法を探しています。代わりに、Java で直接変換したいと思います。
さまざまな提案(123 ) を試しましたが、これまでのところ何も機能していません。
DKIM for Java は、DER ファイルを次のように処理します。

    File privKeyFile = new File(privkeyFilename);

    // read private key DER file
    DataInputStream dis = new DataInputStream(new FileInputStream(privKeyFile));
    byte[] privKeyBytes = new byte[(int) privKeyFile.length()];
    dis.read(privKeyBytes);
    dis.close();

    KeyFactory keyFactory = KeyFactory.getInstance("RSA");

    // decode private key
    PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(privKeyBytes);
    RSAPrivateKey privKey = (RSAPrivateKey) keyFactory.generatePrivate(privSpec);

結局、私が必要とするのはRSAPrivateKey.

RSAPrivateKeyJavaMail の DKIM が RSA 秘密鍵から必要とするこれを簡単に生成するにはどうすればよいですか?

4

2 に答える 2

4

あなたの参照3(のみ)は正しいです。あなたの問題は、PEMをDERに変換するだけではなく(@Jimが言うように、基本的にはbase64をバイナリに変換するだけです)、opensslの「従来の」または「レガシー」または「PKCS#1」形式のキーデータを含むPEMを、PKCSを含むDERに変換することです。 #8 (具体的には PKCS#8 クリア/非暗号化) 形式のキー データ。

Alistairの回答で指摘されているhttp://juliusdavies.ca/commons-ssl/pkcs8.htmlは可能性のように見えますが、詳しくは調べませんでした。RSA の PKCS#8 clear (PrivateKeyInfo) は PKCS#1 の単純な ASN.1 ラッパーであるため、次の (ちょっと) クイックで (非常に) 汚いコードは最小限のソリューションを提供します。入力読み取りロジック (およびエラー処理) を変更して、使用可能な base64 デコーダーを試して置き換えます。

    BufferedReader br = new BufferedReader (new FileReader (oldpem_file));
    StringBuilder b64 = null;
    String line;
    while( (line = br.readLine()) != null )
        if( line.equals("-----BEGIN RSA PRIVATE KEY-----") )
            b64 = new StringBuilder ();
        else if( line.equals("-----END RSA PRIVATE KEY-----" ) )
            break;
        else if( b64 != null ) b64.append(line);
    br.close();
    if( b64 == null || line == null ) 
        throw new Exception ("didn't find RSA PRIVATE KEY block in input");

    // b64 now contains the base64 "body" of the PEM-PKCS#1 file
    byte[] oldder = Base64.decode (b64.toString().toCharArray());

    // concatenate the mostly-fixed prefix plus the PKCS#1 data 
    final byte[] prefix = {0x30,(byte)0x82,0,0, 2,1,0, // SEQUENCE(lenTBD) and version INTEGER 
            0x30,0x0d, 6,9,0x2a,(byte)0x86,0x48,(byte)0x86,(byte)0xf7,0x0d,1,1,1, 5,0, // AlgID for rsaEncryption,NULL
            4,(byte)0x82,0,0 }; // OCTETSTRING(lenTBD) 
    byte[] newder = new byte [prefix.length + oldder.length];
    System.arraycopy (prefix,0, newder,0, prefix.length);
    System.arraycopy (oldder,0, newder,prefix.length, oldder.length);
    // and patch the (variable) lengths to be correct
    int len = oldder.length, loc = prefix.length-2; 
    newder[loc] = (byte)(len>>8); newder[loc+1] = (byte)len;
    len = newder.length-4; loc = 2;
    newder[loc] = (byte)(len>>8); newder[loc+1] = (byte)len;

    FileOutputStream fo = new FileOutputStream (newder_file);
    fo.write (newder); fo.close();
    System.out.println ("converted length " + newder.length);

余談ですが、投稿されたデータのABCCが編集されたと思います。有効で妥当な PKCS#1 (クリア) RSA キーは、バイト 0x30 0x82 x で始まる必要があります。x は 2 から約 9 です。base64 に変換する場合、これは MIIC から MIIJ で始まる必要があります。

于 2014-05-18T00:28:40.187 に答える
0

PEM 形式は、Base64 でエンコードされた DER バイトです。PEM ファイルをテキスト ファイルとして読み取るだけで、"-----BEGIN RSA PRIVATE KEY-----" と "-----END RSA PRIVATE KEY----" の間の行のみを取得できます。 -」。

PEM ファイルではコメントが許可されているため、「-----BEGIN RSA PRIVATE KEY-----」に到達するまで、最初から追加の行をスキップする必要がある場合があります。

これは、テキストを Base64 でデコードするだけで PEM を DER に変換する Ruby のコードです。これを Java に変換できます。

require 'base64'

# Read the PEM as text
pem = File.read('key.pem')

# Break into individual lines
all_lines = pem.split("\n")

# Discard the first and last lines
b64_lines = all_lines[1..-2]

# Write the output file
File.open('key.der', 'w') do |f|
    # For each line
    b64_lines.each do |line|
        # Write the Base64-decoded bytes
        f.write Base64.decode64(line)
    end
end

これは、作成したばかりの RSA キーを表示する openssl です。

$ openssl rsa -text -in key.pem
Private-Key: (2048 bit)
modulus:
    00:aa:8d:15:05:db:a3:fa:bb:dc:8d:4f:d5:53:56:
    d6:78:7f:41:6d:05:b9:92:a4:7c:28:b1:11:50:9e:
    77:67:04:e9:77:22:62:db:1f:43:bc:f2:5e:fc:f3:
    42:35:a2:01:9c:9c:c1:90:b7:2b:1c:c8:51:f2:27:
... (omitted)

以下は、Ruby コードが記述した DER ファイルを表示する openssl です。

$ openssl rsa -text -inform DER -in key.der
Private-Key: (2048 bit)
modulus:
    00:aa:8d:15:05:db:a3:fa:bb:dc:8d:4f:d5:53:56:
    d6:78:7f:41:6d:05:b9:92:a4:7c:28:b1:11:50:9e:
    77:67:04:e9:77:22:62:db:1f:43:bc:f2:5e:fc:f3:
    42:35:a2:01:9c:9c:c1:90:b7:2b:1c:c8:51:f2:27:
...

これはPEMでした(中央部分は省略):

-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAqo0VBduj+rvcjU/VU1bWeH9BbQW5kqR8KLERUJ53ZwTpdyJi
2x9DvPJe/PNCNaIBnJzBkLcrHMhR8ici2aOpuPZi/EDxjRcNPF1Bj+ULvYNLMEDb
2ng9HhyyQtZMllYpkuewONSsTfrsOKEm3NXFfjAclVAGUHp6JpBCTfd32VbHGmJl
...
S4SwxwUV39H2Zq+X1pSIEssSUduyGvF7jJadHe5OiacD5112bkF+Tx/YThMcMebg
8IrO8DyBIBfgAcQPq2GSY99ImacZ++OLXcXdC9NYZ3U9T2SCJdf5
-----END RSA PRIVATE KEY-----
于 2014-05-17T18:44:07.890 に答える