可以使用具有 AES 和 rsaEncryption 的信封 CMS(PKCS#1 v1.5 填充而不是 v2 (OAE

本文关键字:v1 PKCS#1 填充 OAE v2 CMS AES rsaEncryption 可以使 | 更新日期: 2023-09-27 18:36:04

我一直在使用.NET进行加密。到目前为止,我将3DES(Oid 1.2.840.113549.3.7)与rsaEncryption(Oid 1.2.840.113549.1.1.1,RSAES-PKCS1-v1_5)结合使用。虽然第一个现在必须被AES(Oid 2.16.840.1.101.3.4.1.42)取代,但我仍然必须使用rsaEncryption/RSAES-PKCS1-v1_5,而不是RSAES-OAEP

如果我只是将一个额外的参数传递给我正在调用的 EnvelopedCMS 构造函数,我可以从 3DES 切换到 AES:

    ContentInfo plainContent = new ContentInfo(new Oid("1.2.840.113549.1.7.1"), data);
    EnvelopedCms encryptedMessage = new EnvelopedCms(plainContent); // using 3DES
    // EnvelopedCms encryptedMessage = new EnvelopedCms(plainContent, new AlgorithmIdentifier(new Oid("2.16.840.1.101.3.4.1.42")));  // for AES (id-aes256-CBC)
    CmsRecipient recipient = new CmsRecipient(cert);
    encryptedMessage.Encrypt(recipient);
    byte[] encryptedBytes = encryptedMessage.Encode();

到目前为止还好。不幸的是,有些收件人无法解密我的邮件,尽管他们能够解密AES。查看ASN.1结构告诉我,不仅3DES更改为AES,而且rsaEncryption(1.2.840.113549.1.1.1)也被RSAES-OAEP(1.2.840.113549.1.1.7)取代。我可以以某种方式强制仍然将RSAES-PKCS1-v1_5与EnvelopedCMS一起使用吗?或者您是否看到切换 3DES->AES 的另一个问题?

编辑:如果我无法轻松地将填充更改为v1.5,我还有什么其他选择?手动调用加密服务提供者并自行构建 PKCS#7 信封?还有更优雅的方式吗?

可以使用具有 AES 和 rsaEncryption 的信封 CMS(PKCS#1 v1.5 填充而不是 v2 (OAE

.NET Framework EnvelopedCms 构建在 Windows CAPI CryptMsg* 函数之上。CryptMsgOpenToEncode支持两种对收件人进行编码的方式,其中一种是有条件编译的(尽管我无法识别何时不可用;我怀疑这是一个Win9x与NT4/WinXP兼容问题)。

我一时兴起,看看什么可以翻转它以使用其他代码路径,以及这是否会改变您在此处的结果。事实证明,是的,使其内部"useCms"会导致收件人加密算法为 1.2.840.113549.1.1.1。

选项 1)使用主题键标识符标识

如果要与其他系统进行互操作(如此处的情况),请确保证书具有显式的 SubjectKeyIdentifier 扩展名,然后再使用此标识表单。 如果没有显式值,.NET/Windows 将构成一个隐式值,在这种情况下,并非所有 CMS 实现都与收件人证书匹配(例如 OpenSSL)。

您可以通过将 CmsRecipient 更改为

CmsRecipient recipient = new CmsRecipient(SubjectIdentifierType.SubjectKeyIdentifier, cert);

选项 2)添加不受保护的属性

信封 Cms 允许将其他元数据添加到未加密的消息中。指定这些值中的任何一个都会使加密器/编码器使用备用代码路径。

在调用加密之前添加

// Pkcs9DocumentName requires a non-empty string.
// You can use any AsnEncodedData value, though.
encryptedMessage.UnprotectedAttributes.Add(new Pkcs9DocumentName("a"));

他们每个人都在本地测试中工作。