在 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
我使用以下代码将 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