在 C# 中使用 512 位 public 密钥验证 RSA 符号

Verify RSA sign with 512 bit public key in C#

我使用以下代码将 X.509 public 密钥转换为 C# RSAParameters,它适用于 1024 位密钥。但是对于 512 位密钥,rsa.VerifyData(data, new SHA1CryptoServiceProvider(), sign) return false.

我用 public 中的 Java 键验证了符号、数据是正确的。

byte[] keyBytes = Convert.FromBase64String(publicKeyString);

byte[] modulus;
switch (keyBytes.Length)
{
    case 94: // 512 bits
        modulus = new byte[65];
        Array.Copy(keyBytes, 24, modulus, 0, modulus.Length);
        break;
    case 162: // 1024 bits
        modulus = new byte[128];
        Array.Copy(keyBytes, 29, modulus, 0, modulus.Length);
        break;
    default:
        throw new NotSupportedException();
}

byte[] publicExponent = new byte[3];
Array.Copy(keyBytes, keyBytes.Length - 3, publicExponent, 0, 3);

var para = new RSAParameters();
para.Modulus = modulus;
para.Exponent = publicExponent;

...

此外,此单元测试已通过:

byte[] modulus = new byte[65];
Array.Copy(keyBytes, 24, modulus, 0, modulus.Length);
Array.Reverse(modulus); // big-endian
if ((modulus[modulus.Length - 1] & 0x80) > 0) // make sure positive 
{
    var temp = new byte[modulus.Length];
    Array.Copy(modulus, temp, modulus.Length);
    modulus = new byte[temp.Length + 1];
    Array.Copy(temp, modulus, temp.Length);
}
var mFromByte = new BigInteger(modulus);
var mFromStr = BigInteger.Parse("10446137350258867541972982874422299386188841602828508348451210482770166585987014109048441013963536226102851240621532747362919294772011580690442657343607779"); // <- modulus output by java

Assert.AreEqual(0, mFromByte.CompareTo(mFromStr));

感谢@Iridium 的指正,当然512位模数应该是512位。我像这样更改代码 verify returns true.

case 94:
    modulus = new byte[64];
    Array.Copy(keyBytes, 25, modulus, 0, modulus.Length);
    break;

在public密钥的二进制中,第24行描述的模数是在65位之后,但是第25行的0只是一个标志。

24  01000001    LEN(short format, 65 bits)
25  00000000