如何提取 RSACryptoServiceProvider 生成的素数?
Posted
技术标签:
【中文标题】如何提取 RSACryptoServiceProvider 生成的素数?【英文标题】:How to extract the prime numbers generated by RSACryptoServiceProvider? 【发布时间】:2017-10-10 15:14:25 【问题描述】:以下代码试图获取RSACryptoServiceProvider
生成的两个 RSA 素数。我正在测试primeq
的素数,它总是变成非素数。我在这里做错了什么?
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(384);
var p = rsa.ExportParameters(true);
var primeq = new BigInteger(p.Q);
【问题讨论】:
RSAParameters
字段以大端顺序返回。 BigInteger
byte[] 构造函数需要一个 little-endian 顺序参数。所以颠倒顺序,别忘了诅咒微软的粗心和愚蠢。
@JamesKPolk - 我不认为这是粗心或愚蠢。 Microsoft 操作系统和软件在 little-endian 的机器上运行。甚至 ARM 小工具也以小端模式与 CPU 一起运行。这是一个简单和高效的问题。微软可以更好地记录它。
@jww:粗心和愚蠢来自于在一个地方使用小端,而在另一个地方使用大端。 CPU 的字节序应该与导出的大整数表示的字节序几乎没有相关性。最后,我仍然在 RSAParameters 字段的文档中找不到任何提到字节序的内容。这真是太棒了。
@JamesKPolk - 看看...微软正在更好地记录它:cryptoapi little endian msdn。我希望我能找到那篇为您讨论设计决策的文章。甚至 OpenSSL 也是为了简单和高效(参见 BN_bn2lebinpad
和 BN_bin2lbn
文档)。我真的没有看到粗心或愚蠢。它们是实现特定目标的设计决策。
【参考方案1】:
我自己也遇到过这个问题。我发现其实有两个问题:
-
首先,
BigInteger
使用与 RSACryptoServiceProvider
不同的字节序
BigInteger
是有符号的并使用补码符号,而 RSA 密钥是无符号整数。
为了解决这个问题,我将修改您的代码如下:
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(384);
var p = rsa.ExportParameters(true);
var primeq = new BigInteger(p.Q.Reverse().Concat(new Byte[1]).ToArray());
这是用以下代码测试的:
using (var rsa = new RSACryptoServiceProvider())
var a = rsa.ExportParameters(true);
BigInteger p = new BigInteger(a.P.Reverse().Concat(new byte[1]).ToArray());
BigInteger q = new BigInteger(a.Q.Reverse().Concat(new byte[1]).ToArray());
BigInteger n = new BigInteger(a.Modulus.Reverse().Concat(new byte[1]).ToArray());
Console.WriteLine(p * q == n);
【讨论】:
以上是关于如何提取 RSACryptoServiceProvider 生成的素数?的主要内容,如果未能解决你的问题,请参考以下文章