当前位置: 首页 > 知识库问答 >
问题:

BouncyCastle和PKCS#1 v2.1,与RSASSA-PSS签约

杜英叡
2023-03-14

我花了无数个小时在这个图书馆里,但仍然无法让它工作。

我想用充气城堡库发送SMIME消息,用RSASSA-PSS签名,用AES加密,其中密钥传输应该是RSAES-OAEP,所有P1#v2.1

签名者优先,这是它的创建方式:

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/OAEPESS SHA256AndMGF1Padd”?如果第一个参数是公钥算法,第二个“ECB”是我假设的ECB AES模式,我是对的吗?(我也尝试了CBC模式,但没有这样的算法异常,也尝试了NONE)最后一个(“OAEPRetSHA56AndMGF1Padd”)显然是OAEP p1#v2.1,这是我真正想要的。

因此,此时应该对消息进行签名

但是,当我和老签名人签约的时候

build("SHA256withRSAEncryption", pk.getPrivateKey(), pk.getCertificate()

并使用旧的密钥传输方案

setProvider("BC").setAlgorithmMapping(PKCSObjectIdentifiers.rsaEncryption, "RSA/NONE/PKCS1Padding");

一切都很顺利。显然,我的自签名x509证书在这里不是问题,如果我在这里打电话,请纠正我。

我还使用Outlook(2013)对其进行了测试

旧方案(SHA256带RSA加密签名PKCS1添加密钥传输)-

新方案(SHA256带有RSA和MGF1签名RSA/ECB/OAEP带有SHA256和MGF1填充)-

在这一点上,我不知道到底是什么错了。以下是我使用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

共有3个答案

左丘繁
2023-03-14

我认为问题在于大多数S/MIME客户端不支持RSASSA-PSS。我发现唯一支持验证S/MIME RSASSA-PSS签名的工具(除了BC)是openssl的最新版本。

根据openssl文档,这需要openssl

openssl cms-验证-在电子邮件中。eml-咖啡根。质子交换膜

这仅适用于openssl cms命令,而不适用于openssl smime命令。

屠振濂
2023-03-14

我想我解决了你的问题。至少在我的情况下,它起作用了。用于PKCSObjectIdentifiers的算法标识符。我添加了以下代码行:

pubilc AlgorithmIdentifier getAlgo() {

        JcaAlgorithmParametersConverter paramsConverter = new JcaAlgorithmParametersConverter();
        OAEPParameterSpec oaepSpec = new OAEPParameterSpec("SHA-256", "MGF1", new MGF1ParameterSpec("SHA-256"), new PSource.PSpecified(new byte[]{1, 2, 3, 4, 5}));
    return paramsConverter.getAlgorithmIdentifier(PKCSObjectIdentifiers.id_RSAES_OAEP, oaepSpec);
}

使用此参数化算法标识符,您现在可以加密您的邮件:

AlgorithmIdentifier algo = getAlgo();
    SMIMEEnvelopedGenerator encrypter = new SMIMEEnvelopedGenerator();
    RecipientInfoGenerator keyTransportRecipient = 
                            new JceKeyTransRecipientInfoGenerator(cert).setProvider("BC").setAlgorithmMapping(PKCSObjectIdentifiers.id_RSAES_OAEP, "RSA/ECB/OAEPWithSHA256AndMGF1Padding");

encrypter.generate(bodyPart, new JceCMSContentEncryptorBuilder(algo).setProvider("BC").build());                            encrypter.addRecipientInfoGenerator(keyTransportRecipient);

你在签约问题上取得了成功吗?在我的情况下,Outlook说签名无效。

冀崇凛
2023-03-14

将RSA-OAEP的算法标识符提供给OutputEncryptor是错误的。这将(至少对我而言)导致如下错误:

 ... no such algorithm: 1.2.840.113549.1.1.7 for provider BC

如果要使用AES和RSA-OAEP,则必须将AES分配给OutputEncryptor(负责对称加密)和RSA-OAEP分配给RecipientInfoGenerator(分别负责密钥加密和非对称加密)。

代码如下:

(前面的一篇文章已经正确解释了OAEPParameterSpec的定义)。

// Note that at JcaAlgorithmParametersConverter is available since BC 1.50.
JcaAlgorithmParametersConverter paramsConverter = new JcaAlgorithmParametersConverter();
OAEPParameterSpec oaepParameters = new OAEPParameterSpec("SHA-256", "MGF1", new MGF1ParameterSpec(
        "SHA-256"), PSource.PSpecified.DEFAULT);
AlgorithmIdentifier idRsaOaep = paramsConverter.getAlgorithmIdentifier(PKCSObjectIdentifiers.id_RSAES_OAEP, oaepParameters);

SMIMEEnvelopedGenerator encryptor = new SMIMEEnvelopedGenerator();

// Assign OAEPParameterSpec and an instance of X509Certificate to the RecipientInfoGenerator.
// prov is an instance of BouncyCastleProvider.
encryptor.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(certificate, idRsaOaep)
        .setProvider(prov));

// Use an OutputEncryptor with AES.
OutputEncryptor outputEncryptor = new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC)
        .setProvider(prov)
        .build();

// Do encryption (were plaintextMsg is a MimeMessage instance).
MimeBodyPart payload = encryptor.generate(plaintextMsg, outputEncryptor);
 类似资料:
  • 我想分两步使用RSA/PSS签名制作SHA256,首先散列一条消息,然后使用RSASSA-PSS签名摘要 但我使用SHA256时RSA/PSS无法验证 我需要一些帮助,谢谢你的帮助。

  • 我们使用Chilkat在PowerBuilder 9.0.3应用程序(以及PowerBuilder 12.6)中签名HTTP请求,但这就像Chilkat生成的签名不被Isabel的API接受(我们已经联系了Isabel,他们猜测签名中存在参数问题算法)。伊莎贝尔API(https://documentation.ibanity.com/http-signature)的留档说,我们必须使用带有以下参

  • 我已经把它归结为我能做的最简单的测试用例。我需要获取Python中生成的RSASSA-PSS签名,并在Go中验证它们。创建RSA密钥对并用其签名的Python代码如下: 那里引用的pycrypto_keys库可以在这里找到,用于参考函数和的具体实现。 我的Go测试由两个简单的文件组成,这些文件只依赖于核心包。首先是验证功能,verify.go: 第二,一个测试用例。密钥对和签名是使用顶部的Pyth

  • 有人知道RSACryptoServiceProvider使用哪种签名算法吗。签名杂凑?我相信它是RSAPKCS1,它还安全吗? 有没有人想过将RSASSA-PSS配置为RSACryptServiceProvider的签名算法,而不使用像BouncyCastle这样的第三方库? 提前谢谢。

  • 我正在研究PKSC1V2.2 RSASSA-PSS签名方案。我得到了一些用于最终结果测试的标准测试向量,但是我的结果不匹配。为了检查我的代码哪里出错了,我需要一些具有中间结果的测试向量。 我使用的是RSA 2048和SHA 256。 请帮助...如果有人有或者如果你知道我在哪里可以得到它?还有任何其他方法来测试它。 问候

  • 我不确定我是应该在这里问这个问题,还是在安全交换中问这个问题。 无论如何,我最近正在使用TPM处理RSA签名,遇到了一个问题,我将填充方案从RSASSA-PKCS1-v1_5切换到RSASSA-PSS。我认为这应该不会有什么不同,但我注意到一个例子在TSS. MSR(。NET TPM库)不再起作用。我在https://github.com/microsoft/TSS.MSR/issues/109.