110,534
社区成员
发帖
与我相关
我的任务
分享
/// <summary>
/// 验证RSA签名
/// </summary>
/// <param name="str_DataToVerify">待签名的字符串</param>
/// <param name="str_SignedData">对方生成的RSA签名</param>
/// <param name="str_Public_Key">对方公钥</param>
public static bool VerifySignedHash(string str_DataToVerify, string str_SignedData, string str_Public_Key)
{
byte[] SignedData = Convert.FromBase64String(str_SignedData);
ASCIIEncoding ByteConverter = new ASCIIEncoding();
byte[] DataToVerify = ByteConverter.GetBytes(str_DataToVerify);
try
{
RSACryptoServiceProvider RSAalg = new RSACryptoServiceProvider();
byte[] pubKeyBytes = Convert.FromBase64String(str_Public_Key);
RSAalg.ImportCspBlob(pubKeyBytes);
return RSAalg.VerifyData(DataToVerify, new SHA1CryptoServiceProvider(), SignedData);
}
catch (CryptographicException e)
{
return false;
}
}
/// <summary>
/// 验证签名
/// </summary>
/// <param name="content">待签名字符串</param>
/// <param name="signedString">POST过来的签名</param>
/// <param name="publicKey">公钥</param>
/// <param name="input_charset">编码格式</param>
/// <returns></returns>
public static bool verify(string content, string signedString, string publicKey, string input_charset)
{
bool result = false;
try
{
Encoding code = Encoding.GetEncoding(input_charset);
byte[] Data = code.GetBytes(content);
byte[] data = Convert.FromBase64String(signedString);
RSAParameters paraPub = ConvertFromPublicKey(publicKey);
RSACryptoServiceProvider rsaPub = new RSACryptoServiceProvider();
rsaPub.ImportParameters(paraPub);
SHA1 sh = new SHA1CryptoServiceProvider();
result = rsaPub.VerifyData(Data, sh, data);
return result;
}
catch (Exception ex)
{
return false;
}
}
#region 解析.net 生成的Pem
private static RSAParameters ConvertFromPublicKey(string pemFileConent)
{
byte[] keyData = Convert.FromBase64String(pemFileConent);
if (keyData.Length < 162)
{
throw new ArgumentException("pem file content is incorrect.");
}
byte[] pemModulus = new byte[128];
byte[] pemPublicExponent = new byte[3];
Array.Copy(keyData, 29, pemModulus, 0, 128);
Array.Copy(keyData, 159, pemPublicExponent, 0, 3);
RSAParameters para = new RSAParameters();
para.Modulus = pemModulus;
para.Exponent = pemPublicExponent;
return para;
}
SEQUENCE(2 elem)
--SEQUENCE(2 elem)
----OBJECT IDENTIFIER 1.2.840.113549.1.1.1
----NULL
--BIT STRING(1 elem)
----SEQUENCE(2 elem)
------INTEGER(1024 bit) 1324925806459412787721713702712958489781723…
------INTEGER 65537
其中最后的65537就是publicKey中的Exponent,而那个1024bit的数据就是publicKey中的Modulus。
如果是实时解码,可能你要写一个DER解析器。
如果是一次性解码,可以投机直接裁出:
byte[] bytes = Convert.FromBase64String(publicKey);
if (bytes.Length != 0xa2)
{
throw new NotImplementedException();
}
if (!bytes.Skip(bytes.Length - 5).SequenceEqual(new byte[]{2,3,1,0,1}))
{
// 确认Exponent在最后,并且是65537
// 其中2表示ASN整数型,3表示整数数据的字节数,1,0,1就是0x101,就是65537
throw new NotImplementedException();
}
RSAParameters rsaParam = new RSAParameters()
{
Exponent = new byte[]{ 1, 0, 1 }, //65537
Modulus = bytes.Skip(bytes.Length - 5 - 1024).Take(1024).ToArray(), // BCACFA...
};
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.ImportParameters(rsaParam);