Java:将DKIM私钥从RSA转换为JavaMail的DER

我正在使用DKIM for JavaMail与DKIM签署外发邮件。

我的私人DKIM密钥是使用生成的,opendkim-genkey -s default -d example.com如下所示:

-----BEGIN RSA PRIVATE KEY-----

ABCCXQ...[long string]...SdQaZw9

-----END RSA PRIVATE KEY-----

DKIM for JavaMail库需要DER格式的私有DKIM密钥,如其自述文件所述:

DKIM for JavaMail需要DER格式的私钥,您可以使用openssl转换PEM密钥:

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

-outform der

我正在寻找一种避免必须使用openssl将密钥转换为DER格式的方法。相反,我想直接用Java进行转换。

我已经尝试了不同的建议,但到目前为止,没有奏效。

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

回答:

您的参考文献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开头。

以上是 Java:将DKIM私钥从RSA转换为JavaMail的DER 的全部内容, 来源链接: utcz.com/qa/402823.html

回到顶部