【问题标题】:EnvelopedCMS with AES and rsaEncryption (PKCS#1 v1.5 padding instead of v2 (OAEP) padding) possible?带有 AES 和 rsaEncryption(PKCS#1 v1.5 填充而不是 v2 (OAEP) 填充)的 EnvelopedCMS 可能吗?
【发布时间】:2016-02-23 21:39:41
【问题描述】:

我一直在使用 .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,我还有哪些其他选择?手动调用 CryptoServiceProviders 并自己构建 PKCS#7 信封?还有更优雅的方式吗?

【问题讨论】:

  • 我用谷歌搜索了很多,但找不到太多。请注意,PKCS#1 v1.5 有一些您可能希望避免的重大漏洞(在 RSA v2.1 RFC 中进行了解释)。它可能是安全的,但确实需要进行大量检查才能确保安全。 OAEP确实在协议的安全性方面更有意义。
  • 据我所知,我更喜欢 OAEP。不幸的是,我只需要遵循给定的协议。因为我的消息自 3des->aes 以来无法解密,与给定规则相比,我的系统中唯一的区别是使用 OAEP 而不是 rsaEncryption。任何其他的实现想法(最好只使用 .NET 类)?
  • 就我目前的理解而言,BouncyCastle 非常强大(尽管对于 C# 没有很好的文档记录)。任何想法如何在那里实现解决方案?
  • 我在为 Bouncy Castle 实施解决方案时不会遇到太多问题,因为它会飘回给我。它当然是可配置的,如果不是,至少很容易获得源代码。不幸的是,虽然我不知道解决方案。我当然会认为它是解决这个特定问题的好人选。万一它不支持该解决方案,您可以简单地修复并重新编译它。
  • 感谢您的考虑。由于截止日期对此施加了很大压力,因此我现在使用了一个商业库 (cryptosys.net),为该特定问题提供了开箱即用的解决方案。希望现在应该暂时解决这个问题。很抱歉没有最终提供仅使用 .NET 的流畅解决方案。

标签: c# encryption cryptography aes rsa


【解决方案1】:

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

一时兴起,我想看看什么可以翻转它以使用其他代码路径,以及这是否会改变您的结果。事实证明,是的,将其设置为内部“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 允许将其他元数据添加到未加密的消息中。指定这些值中的任何一个都会使加密器/编码器使用备用代码路径。

在调用 Encrypt 之前添加

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

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

【讨论】:

  • 您好,非常感谢您的回答!你明白为什么添加 UnprotectedAttribute -or- using SubjectIdentifierType.SubjectKeyIdentifier 会将 KEA 更改为 RSA (1.2.840.113549.1.1.1)?
  • @PawelLesnikowski 这两个功能出现在更高版本的 CMS 规范中,因此需要对 Windows 进行更新的 API 调用。旧形式只需要一个证书并选择 OAEP(因为它在某些攻击模型下具有更好的安全性)。较新的形式将加密算法作为输入,.NET 使用证书的公钥算法标识符 (RSA) 填充该算法,而不会将 RSA 提升为 RSA_OAEP。
  • useCms==false 是新版本吗?
  • @PawelLesnikowski 否,useCms==true 表示它使用 CMSG_ENVELOPED_ENCODE_INFO (msdn.microsoft.com/en-us/library/windows/desktop/…) 的 rgCmsRecipients 字段,而不是 rgpRecipents。但这显着改变了 .NET 和 Windows 之间的交互。
  • 我了解机制(我认为),但我不明白原因。为什么有 2 种加密信封 cms 的方法?我是否正确理解 UnprotectedAttributes 是“新”API?如果是这样,为什么使用它会强制 AES 与旧的密钥交换一起使用(RSA 而不是 RSAES-OAEP)
猜你喜欢
  • 2023-03-17
  • 2012-04-30
  • 1970-01-01
  • 1970-01-01
  • 2019-01-27
  • 2013-11-14
  • 2020-12-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多