RSA 加密中模数和 p*q 的不匹配值
Non-matching values for modulus and p*q in RSA encryption
我目前正在做一个涉及 RSA 加密的密码学项目。我使用 RSACryptoServiceProvider class 生成值 p、q 和 n(模数)。由于 n = pq,我决定测试这两个值(即 pq 和 n)是否匹配。当我使用 BigInteger class 将 p 和 q 相乘时,我得到了与从 RSACryptoServiceProvider class 生成的 n 不同的答案。代码如下:
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
//export rsa parameters i.e. p , q , e and d
RSAParameters rsaparams = rsa.ExportParameters(true);
//set the p parameter
byte[] p = rsaparams.P;
Array.Reverse(p);
BigInteger primeP = new BigInteger(p);
//set the Q parameter
byte[] q = rsaparams.Q;
Array.Reverse(q);
BigInteger primeQ = new BigInteger(q);
//set the d parameter
byte[] d = rsaparams.D;
Array.Reverse(d);
BigInteger privexponent = new BigInteger(d);
//set the e parameter
byte[] e = rsaparams.Exponent;
Array.Reverse(e);
BigInteger pubexponent = new BigInteger(e);
//set the m parameter
byte[] m = rsaparams.Modulus;
Array.Reverse(m);
BigInteger modulus = new BigInteger(m);
Console.WriteLine("p:\n{0}\n", primeP);
Console.WriteLine("q:\n{0}\n", primeQ);
Console.WriteLine("modulus:\n{0}\n", modulus);
Console.WriteLine();
//perform multiplication of p and q manually
Console.WriteLine(BigInteger.Multiply(primeP, primeQ));
有办法解决这个问题吗?
问题是反转数组是不够的。因为它们是无符号的,所以它们还需要根据数组末尾的值进行填充。
如果数组末尾的值 >= 128,则设置该值的高位,BigInteger
的 byte[]
构造函数将其解释为负号。在这种情况下添加 0 可以防止这种情况。
public static BigInteger FromBigEndian(byte[] p)
{
var q = p.Reverse();
return new BigInteger((p[0] < 128 ? q : q.Concat(new byte[] { 0 })).ToArray());
}
改为如下转换参数
byte[] p = rsaparams.P;
BigInteger primeP = FromBigEndian(p);
我目前正在做一个涉及 RSA 加密的密码学项目。我使用 RSACryptoServiceProvider class 生成值 p、q 和 n(模数)。由于 n = pq,我决定测试这两个值(即 pq 和 n)是否匹配。当我使用 BigInteger class 将 p 和 q 相乘时,我得到了与从 RSACryptoServiceProvider class 生成的 n 不同的答案。代码如下:
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
//export rsa parameters i.e. p , q , e and d
RSAParameters rsaparams = rsa.ExportParameters(true);
//set the p parameter
byte[] p = rsaparams.P;
Array.Reverse(p);
BigInteger primeP = new BigInteger(p);
//set the Q parameter
byte[] q = rsaparams.Q;
Array.Reverse(q);
BigInteger primeQ = new BigInteger(q);
//set the d parameter
byte[] d = rsaparams.D;
Array.Reverse(d);
BigInteger privexponent = new BigInteger(d);
//set the e parameter
byte[] e = rsaparams.Exponent;
Array.Reverse(e);
BigInteger pubexponent = new BigInteger(e);
//set the m parameter
byte[] m = rsaparams.Modulus;
Array.Reverse(m);
BigInteger modulus = new BigInteger(m);
Console.WriteLine("p:\n{0}\n", primeP);
Console.WriteLine("q:\n{0}\n", primeQ);
Console.WriteLine("modulus:\n{0}\n", modulus);
Console.WriteLine();
//perform multiplication of p and q manually
Console.WriteLine(BigInteger.Multiply(primeP, primeQ));
有办法解决这个问题吗?
问题是反转数组是不够的。因为它们是无符号的,所以它们还需要根据数组末尾的值进行填充。
如果数组末尾的值 >= 128,则设置该值的高位,BigInteger
的 byte[]
构造函数将其解释为负号。在这种情况下添加 0 可以防止这种情况。
public static BigInteger FromBigEndian(byte[] p)
{
var q = p.Reverse();
return new BigInteger((p[0] < 128 ? q : q.Concat(new byte[] { 0 })).ToArray());
}
改为如下转换参数
byte[] p = rsaparams.P;
BigInteger primeP = FromBigEndian(p);