【问题标题】:Microsoft RSA CSP key sizeMicrosoft RSA CSP 密钥大小
【发布时间】:2011-12-10 14:12:24
【问题描述】:

据我所知,Microsoft 的 RSA CSP 总是生成相同的位长伪素数。因此,如果密钥大小为 1024,那么 P 和 Q 值似乎(?)保证每个都是 512 位?有谁知道这是否真的如此?

我正在我自己的 RSA 实现和 Microsoft 的实现之间构建一个互操作性模块。就我而言,我在 P & Q 值之间建立了一个小的随机方差,因此对于 1024 位密钥,我最终可能会得到一个值为 506 位和另一个 518 的值。在纯粹的实验基础上,如果我将方差锁定为 0(即P & Q 值的大小相等)- 事情按应有的方式工作,我一旦将大小变量设为 Microsoft RSA 对象,就会在导入过程中响应“错误数据”。

我正在寻找 Microsoft 强制执行相同密钥大小的确认,所以如果有人对此有任何信息,请发布

在有人问我为什么必须实现自己的 RSA 提供程序之前:CryptoAPI 在多线程环境中表现不佳,它会在 CryptoServiceProvider 调用上锁定机器密钥库;如果从多个线程访问,这意味着“找不到文件”(相当神秘)错误

对于那些关心的人,请看这里:http://blogs.msdn.com/b/alejacma/archive/2007/12/03/rsacryptoserviceprovider-fails-when-used-with-asp-net.aspx

【问题讨论】:

  • 对此的快速更新:我已经运行了多次迭代以通过 RSACryptoServiceProvider 生成密钥——每次迭代都会产生相同的密钥大小。
  • 是的,如果需要,MS 将使用 0-pad 并且永远不会使用 a bit (双关语)超过所需的内容,即您将始终使用 bit size/2 P 和 Q。
  • 我可以发誓我在一些 RSA 论文中看到了大致相同的尺寸。不过你是对的,这也解释了为什么他们定义了一组预定义的“合法密钥大小”。

标签: asp.net cryptography keystore cryptoapi rsacryptoserviceprovider


【解决方案1】:

我自己的工作/实验,对Mono 的(托管)RSA 实施和单元测试进行了测试,表明 Microsoft 实施在导入 RSA 参数值时需要特定 byte[] 大小。

当人们使用 BigInteger 转换参数时,这也是一个常见互操作性问题(有一些关于它的问题),因为它们通常比 MS 预期的要小一些(例如少 1 个字节)并且需要用 0 填充。

所以我很确定您可以填充较小的值以使 MS 接受它,但您可能无法使其接受较大的值。

【讨论】:

  • 感谢您的回答——我没有使用大整数,而是(非常!)高度优化和修改的 IntX 类版本 (intx.codeplex.com)。我遇到的最大的互操作性问题是围绕 Big/Little Endian,微软在反转字节顺序方面做了一些奇怪的事情,而不是不可预测的地方。我试图弄清楚 MSFT 在最小大小/跳过大小方面做了什么(如果你有一个 9 位密钥,我的实现会给你 2 个字节 - 有些实现会给你 4 个字节)MSFT 期望什么......谁知道呢。
  • MS 所期望的很多东西都可以追溯到 CryptoAPI(查看 API、结构...)。还可以查看 Mono 的单元测试。如果您希望实现与 MS 之间的最大互操作性,您会发现您的实现应该涵盖许多极端情况。
【解决方案2】:

Microsoft 的 RSA CSP 生成和使用私钥,它可以按照on this page 描述的格式导出和导入,如下所示:

BLOBHEADER blobheader;
RSAPUBKEY rsapubkey;
BYTE modulus[rsapubkey.bitlen/8];
BYTE prime1[rsapubkey.bitlen/16];
BYTE prime2[rsapubkey.bitlen/16];
BYTE exponent1[rsapubkey.bitlen/16];
BYTE exponent2[rsapubkey.bitlen/16];
BYTE coefficient[rsapubkey.bitlen/16];
BYTE privateExponent[rsapubkey.bitlen/8];

因此,CSP 可以处理(尤其是生成)的私钥必须具有以下属性:

  • 模数长度(以位为单位)必须是 16 的倍数。
  • 每个素因数的长度不得超过模数长度的一半。
  • 私有指数不得长于模数。
  • 私有指数,减少模p-1(resp.q-1)必须不超过模数的一半。

从技术上讲,私有指数 d 有无限多可能的值,exponent1 和 exponent2 也是如此,因为在数学上重要的是 d的值> 模 p-1 和 q-1;如果私有指数部分最终得到较低的Hamming weight,则建议接受稍长的私有指数部分,因为这会带来一些性能优势。底线:上述格式不会让你这样做。

密钥必须具有的其他特征必须可以被微软的代码接受(但在上面的描述中没有直接报告):

  • 第一个素数(p,又名prime1)的数值必须大于第二个素数(q,又名prime2)的数值)。
  • 公共指数(此处编码在 rsapubkey 字段中)必须适合 32 位整数(无符号)。

因此,根据RSA standard,有许多名义上有效的 RSA 密钥对,但 Microsoft RSA CSP 代码无法处理这些密钥对。值得注意的是关于公共指数大小的最后一个约束:这意味着该约束比 CSP 更通用;如果您设置一个 SSL 服务器,其中服务器的公钥(在其证书中)有一个不适合 32 位的公共指数,那么 Internet Explorer 将无法连接到它。

因此,在实践中,如果您生成 RSA 密钥对,则必须确保它们符合上述规则。别担心:据我们所知,这些规则不会降低安全性。

【讨论】:

  • 好帖子——我会把规则放进去看看会发生什么。
  • 很好的 P > Q 要求——你知道它来自哪里吗?至于 E - 我将其锁定为 65537,这是通过平方性能求幂的最低汉明权重(嗯,不是 1)。这推动了更长的素数搜索,因为它变成了:do { p = generatePrime(bitsize/2); } 而 ((p % e) ==1)
  • 应用 CRT 时,首先计算 m1 = m^d1 mod p 和 m2 = m^d2 mod q(取幂模 p 和 q)。然后将 m2 模 p 作为 CRT 的初始步骤。如果 p q”要求曾经是 PKCS#1 的一部分(我在自己的代码中有这样的注释)但我在当前的标准版本中找不到它。
猜你喜欢
  • 2020-04-07
  • 1970-01-01
  • 1970-01-01
  • 2012-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-21
相关资源
最近更新 更多