使用AES和rsaEncryption(PKCS#1 v1.5填充而不是v2(OAEP)填充)的EnvelopedCMS可能吗?

我一直在使用.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)取代。 我可以以某种方式强迫仍然使用EnvelopedCMS的RSAES-PKCS1-v1_5吗? 或者您是否在切换3DES-> AES时遇到了另一个问题?

编辑:如果我不能轻易地将填充更改为v1.5,我还有其他选择吗? 手动调用CryptoServiceProviders并自行构建PKCS#7信封? 还有更优雅的方式吗?

.NET Framework EnvelopedCms构建于Windows CAPI CryptMsg *函数之上。 CryptMsgOpenToEncode支持两种编码收件人的方式,其中一种是有条件编译的(虽然我无法识别它何时不可用;我怀疑它是Win9x与NT4 / WinXP compat问题)。

我突发奇想,看看有什么可以翻转它来使用其他代码路径,如果这会改变你的结果。 事实certificate,是的,在内部使用“useCms”会导致收件人加密算法为1.2.840.113549.1.1.1。

选项1)使用SubjectKeyIdentifier标识

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

您可以通过将CmsRecipient更改为来完成此操作

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

选项2)添加UnprotectedAttribute

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

在调用加密之前添加

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

每个人都在本地测试。