【发布时间】:2017-04-04 10:54:23
【问题描述】:
在这个库上花费了无数个小时之后,我仍然无法让它工作。
我想用充气城堡库发送 smime 消息,用 RSASSA-PSS 签名,用 AES 加密,其中密钥传输应该是 RSAES-OAEP,所有 P1#v2.1
Signer first,它是这样创建的:
SMIMESignedGenerator gen = new SMIMESignedGenerator();
SignerInfoGenerator signer
= new JcaSimpleSignerInfoGeneratorBuilder()
.setProvider("BC")
.build("SHA256withRSAAndMGF1", pk.getPrivateKey(), pk.getCertificate()
);
gen.addSignerInfoGenerator(signer);
gen.addCertificates(certStore);
MimeMultipart mmp = gen.generate(message);
所以现在什么时候应该签名、加密和使用 OAEP 填充:
OutputEncryptor enc = new BcCMSContentEncryptorBuilder(CMSAlgorithm.AES192_CBC).build();
SMIMEEnvelopedGenerator gen = new SMIMEEnvelopedGenerator();
for (X509Certificate nCert : certs) {
RecipientInfoGenerator keyTransportRecipient =
new JceKeyTransRecipientInfoGenerator(nCert).setProvider("BC").
setAlgorithmMapping(PKCSObjectIdentifiers.rsaEncryption, "RSA/ECB/OAEPWithSHA256AndMGF1Padding");
gen.addRecipientInfoGenerator(keyTransportRecipient);
}
MimeBodyPart encryptedMimeBodyPart = gen.generate(message, enc);
我找不到正确的 setAlgorithmMapping() 描述,所以我尝试了以下组合:
.setAlgorithmMapping(PKCSObjectIdentifiers.rsaEncryption, "RSA/NONE/PKCS1Padding");
.setAlgorithmMapping(PKCSObjectIdentifiers.rsaEncryption, "RSA/ECB/OAEPWithSHA256AndMGF1Padding");
.setAlgorithmMapping(PKCSObjectIdentifiers.id_RSAES_OAEP, "RSA/ECB/OAEPWithSHA56AndMGF1Padding");
顺便说一句,谁能解释一下,这个模式在这里到底是什么意思 - “RSA/ECB/OAEPWithSHA256AndMGF1Padding”? 如果第一个参数是公钥算法,我是否正确,第二个“ECB”是我想 ECB AES 模式? (我也尝试过 CBC 模式,但没有出现此类算法异常,也尝试过 NONE)最后一个(“OAEPWithSHA56AndMGF1Padding”)显然是 OAEP p1#v2.1,这是我真正想要的。
因此,此时应该对消息进行签名和加密。 当我现在检查我的邮箱时(使用 Thunderbird),它显示:“Thunderbird 无法解密此邮件”、“发件人使用您的一个数字证书加密了此邮件给您,但是 Thunderbird 无法解密找到这个证书和对应的私钥。”
但是,当我和老签名者签约时
build("SHA256withRSAEncryption", pk.getPrivateKey(), pk.getCertificate()
并使用旧的密钥传输方案,即
setProvider("BC").setAlgorithmMapping(PKCSObjectIdentifiers.rsaEncryption, "RSA/NONE/PKCS1Padding");
一切正常。所以显然我的自签名 x509 证书不是这里的问题,如果我在这里,请纠正我。
我还使用 Outlook (2013)
对其进行了测试旧方案(SHA256withRSAEncryption 签名 + PKCS1Padding 密钥传输) -> 一切都很好。
新方案(SHA256withRSAAndMGF1 签名 + RSA/ECB/OAEPWithSHA256AndMGF1Padding) ->“底层安全系统找不到您的数字 ID 名称”错误。
在这一点上,我不知道实际上出了什么问题。 这就是我使用 openssl 创建证书的方式:
openssl req -new -x509 -nodes -sha256 -days 365 -newkey rsa:2048 -out certificate.cer -keyout private.key -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:32 -passin pass:mypass -utf8 -config _openssl.cfg -extensions v3_req
openssl pkcs12 -export -out certificate.pfx -name "testname" -inkey private.key -in certificate.cer
【问题讨论】:
-
"RSA/ECB/OAEPWithSHA256AndMGF1Padding" -> RSA,要使用的密码(OAEP 可以与其他密码一起使用),ECB -> 实际上应该是 None,历史文物,RSA 的加密模式(与此字符串中的 AES 无关)并且 OAEPWithSHA256AndMGF1Padding 是使用 SHA256 为 MGF1 配置的 OAEP。由于 SHA-1 是默认设置,实际上在这里使用是安全的,我会使用它而不是 SHA-256 并尝试一下。在很多情况下,哈希更改是问题所在。
-
我不知道答案,但如果没有其他人回答,请尝试使用 BC 开发邮件列表(并在此处报告!)。
-
对不起,我忘了说哈希函数的选择不是我的,我必须使用sha256
标签: java cryptography rsa bouncycastle signing