RSAParameters 计算私有参数
RSAParameters calculating private parameters
我正在尝试计算 .NET Standard 上 RSAParameters
结构的私有参数。我做了一个单元测试来测试我的计算:
[TestMethod]
public void DQDPTest()
{
RSA rsa = RSA.Create();
RSAParameters rsaParams = rsa.ExportParameters(true);
BigInteger p = new BigInteger(rsaParams.P.Reverse().ToArray());
BigInteger q = new BigInteger(rsaParams.Q.Reverse().ToArray());
BigInteger d = new BigInteger(rsaParams.D.Reverse().ToArray());
BigInteger dq = new BigInteger(rsaParams.DQ.Reverse().ToArray());
BigInteger dp = new BigInteger(rsaParams.DP.Reverse().ToArray());
Assert.AreEqual(dq, d % (q - 1));
Assert.AreEqual(dp, d % (p - 1));
}
然而,断言总是失败,我无法弄清楚为什么,因为 DQ
和 DP
应该包含这些值。为什么会这样?
我有类似的方法计算InverseQ
,这个也不行:
[TestMethod]
public void ModInverseTest()
{
RSA rsa = RSA.Create();
RSAParameters rsaParams = rsa.ExportParameters(true);
BigInteger p = new BigInteger(rsaParams.P.Reverse().ToArray());
BigInteger q = new BigInteger(rsaParams.Q.Reverse().ToArray());
BigInteger iq = new BigInteger(rsaParams.InverseQ.Reverse().ToArray());
BigInteger ciq = Extensions.ModInverse(q, p);
Assert.AreEqual(1, (iq * q) % p);
Assert.AreEqual(1, (ciq * q) % p);
Assert.AreEqual(iq, ciq);
}
public static BigInteger ModInverse(BigInteger a, BigInteger n)
{
BigInteger t = 0, nt = 1, r = n, nr = a;
if (n < 0)
{
n = -n;
}
if (a < 0)
{
a = n - (-a % n);
}
while (nr != 0)
{
var quot = r / nr;
var tmp = nt; nt = t - quot * nt; t = tmp;
tmp = nr; nr = r - quot * nr; r = tmp;
}
if (r > 1) throw new ArgumentException(nameof(a) + " is not convertible.");
if (t < 0) t = t + n;
return t;
}
ModInverseTest()
中的断言也一直失败,这意味着要么我做错了什么,要么这些值根本不是我认为的那样。同样,为什么会这样?
您的 P 和 Q 值几乎肯定是负值,这很可能会影响其他一切。这是因为 C# BigInteger 构造函数不允许您指定 positive/negative,因此设置了最高有效位的最高有效字节意味着它是一个负数。解决方案是添加一个填充字节 (0x00) 以保持符号位清晰。
private static System.Numerics.BigInteger GetBigInteger(byte[] parameter)
{
byte[] signPadded = new byte[parameter.Length + 1];
Buffer.BlockCopy(parameter, 0, signPadded, 1, parameter.Length);
Array.Reverse(signPadded);
return new System.Numerics.BigInteger(signPadded);
}
我正在尝试计算 .NET Standard 上 RSAParameters
结构的私有参数。我做了一个单元测试来测试我的计算:
[TestMethod]
public void DQDPTest()
{
RSA rsa = RSA.Create();
RSAParameters rsaParams = rsa.ExportParameters(true);
BigInteger p = new BigInteger(rsaParams.P.Reverse().ToArray());
BigInteger q = new BigInteger(rsaParams.Q.Reverse().ToArray());
BigInteger d = new BigInteger(rsaParams.D.Reverse().ToArray());
BigInteger dq = new BigInteger(rsaParams.DQ.Reverse().ToArray());
BigInteger dp = new BigInteger(rsaParams.DP.Reverse().ToArray());
Assert.AreEqual(dq, d % (q - 1));
Assert.AreEqual(dp, d % (p - 1));
}
然而,断言总是失败,我无法弄清楚为什么,因为 DQ
和 DP
应该包含这些值。为什么会这样?
我有类似的方法计算InverseQ
,这个也不行:
[TestMethod]
public void ModInverseTest()
{
RSA rsa = RSA.Create();
RSAParameters rsaParams = rsa.ExportParameters(true);
BigInteger p = new BigInteger(rsaParams.P.Reverse().ToArray());
BigInteger q = new BigInteger(rsaParams.Q.Reverse().ToArray());
BigInteger iq = new BigInteger(rsaParams.InverseQ.Reverse().ToArray());
BigInteger ciq = Extensions.ModInverse(q, p);
Assert.AreEqual(1, (iq * q) % p);
Assert.AreEqual(1, (ciq * q) % p);
Assert.AreEqual(iq, ciq);
}
public static BigInteger ModInverse(BigInteger a, BigInteger n)
{
BigInteger t = 0, nt = 1, r = n, nr = a;
if (n < 0)
{
n = -n;
}
if (a < 0)
{
a = n - (-a % n);
}
while (nr != 0)
{
var quot = r / nr;
var tmp = nt; nt = t - quot * nt; t = tmp;
tmp = nr; nr = r - quot * nr; r = tmp;
}
if (r > 1) throw new ArgumentException(nameof(a) + " is not convertible.");
if (t < 0) t = t + n;
return t;
}
ModInverseTest()
中的断言也一直失败,这意味着要么我做错了什么,要么这些值根本不是我认为的那样。同样,为什么会这样?
您的 P 和 Q 值几乎肯定是负值,这很可能会影响其他一切。这是因为 C# BigInteger 构造函数不允许您指定 positive/negative,因此设置了最高有效位的最高有效字节意味着它是一个负数。解决方案是添加一个填充字节 (0x00) 以保持符号位清晰。
private static System.Numerics.BigInteger GetBigInteger(byte[] parameter)
{
byte[] signPadded = new byte[parameter.Length + 1];
Buffer.BlockCopy(parameter, 0, signPadded, 1, parameter.Length);
Array.Reverse(signPadded);
return new System.Numerics.BigInteger(signPadded);
}