RSA加密中模数和p * q的非匹配值

时间:2021-08-19 16:52:00

I am currently doing a cryptography project which involves RSA encryption. I used the RSACryptoServiceProvider class to generate the values p, q and n (modulus). Since n = pq, I decided to test if the two values (i.e. pq and n) match. When I used the BigInteger class to multiply p and q I got a different answer compared to the n as generated from the RSACryptoServiceProvider class. The code is shown below:

我目前正在做一个涉及RSA加密的加密项目。我使用RSACryptoServiceProvider类生成值p,q和n(模数)。由于n = pq,我决定测试两个值(即pq和n)是否匹配。当我使用BigInteger类乘以p和q时,与从RSACryptoServiceProvider类生成的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));

Is there a way of fixing this problem?

有没有办法解决这个问题?

1 个解决方案

#1


The problem is that reversing the arrays is not enough. Because they are unsigned they also require padding depending on the value at the end of the array.

问题是逆转阵列是不够的。因为它们是无符号的,所以它们还需要填充,具体取决于数组末尾的值。

If the value at the end of the array is >= 128 the high bit of that value is set and the byte[] constructor for BigInteger interprets this as a negative sign. Tacking on a 0 in this case prevents this.

如果数组末尾的值> = 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());
}

Convert parameters as follows instead

改为参数如下

byte[] p = rsaparams.P;
BigInteger primeP = FromBigEndian(p);

#1


The problem is that reversing the arrays is not enough. Because they are unsigned they also require padding depending on the value at the end of the array.

问题是逆转阵列是不够的。因为它们是无符号的,所以它们还需要填充,具体取决于数组末尾的值。

If the value at the end of the array is >= 128 the high bit of that value is set and the byte[] constructor for BigInteger interprets this as a negative sign. Tacking on a 0 in this case prevents this.

如果数组末尾的值> = 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());
}

Convert parameters as follows instead

改为参数如下

byte[] p = rsaparams.P;
BigInteger primeP = FromBigEndian(p);