c# Rsa xml pem 校验
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
namespace test
{
/// <summary>
/// RSA签名验证帮助类
/// </summary>
public class RSAHelper
{
/// <summary>
/// 根据路径获取公钥私钥内容
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
public static string getKeyByName(string fileName)
{
string pathName = "";
pathName = pathName + fileName;
using (StreamReader reader = new StreamReader(pathName))
{
string str = reader.ReadToEnd();
return FormatKey(str);
}
}
public static string FormatKey(string key)
{
key = key.Replace("-----BEGIN RSA PRIVATE KEY-----", "");
key = key.Replace("-----END RSA PRIVATE KEY-----", "");
key = key.Replace("-----END PUBLIC KEY-----", "");
key = key.Replace("-----BEGIN PUBLIC KEY-----", "");
key = key.Replace("\r", "");
key = key.Replace("\n", "");
return key;
}
#region 解析PEM私钥成C#可识别的格式
/// <summary>
/// 解析PEM私钥成C#可识别的格式
/// </summary>
/// <param name="privateKey"></param>
/// <returns></returns>
public static RSACryptoServiceProvider DecodeRSAPrivateKey(string privateKey)
{
var RSA = new RSACryptoServiceProvider();
var RSAparams = ConvertFromPemPrivateKey(privateKey);
RSA.ImportParameters(RSAparams);
return RSA;
}
/// <summary>
/// 将pem格式私钥(1024 or 2048)转换为RSAParameters
/// </summary>
/// <param name="pemFileConent">pem私钥内容</param>
/// <returns>转换得到的RSAParamenters</returns>
public static RSAParameters ConvertFromPemPrivateKey(string pemFileConent)
{
if (string.IsNullOrEmpty(pemFileConent))
{
throw new ArgumentNullException("pemFileConent", "This arg cann't be empty.");
}
byte[] keyData = Convert.FromBase64String(pemFileConent);
bool keySize1024 = (keyData.Length == 609 || keyData.Length == 610);
bool keySize2048 = (keyData.Length == 1190 || keyData.Length == 1192);
if (!(keySize1024 || keySize2048))
{
throw new ArgumentException("pem file content is incorrect, Only support the key size is 1024 or 2048");
}
int index = (keySize1024 ? 11 : 12);
byte[] pemModulus = (keySize1024 ? new byte[128] : new byte[256]);
Array.Copy(keyData, index, pemModulus, 0, pemModulus.Length);
index += pemModulus.Length;
index += 2;
byte[] pemPublicExponent = new byte[3];
Array.Copy(keyData, index, pemPublicExponent, 0, 3);
index += 3;
index += 4;
if ((int)keyData[index] == 0)
{
index++;
}
byte[] pemPrivateExponent = (keySize1024 ? new byte[128] : new byte[256]);
Array.Copy(keyData, index, pemPrivateExponent, 0, pemPrivateExponent.Length);
index += pemPrivateExponent.Length;
index += (keySize1024 ? ((int)keyData[index + 1] == 64 ? 2 : 3) : ((int)keyData[index + 2] == 128 ? 3 : 4));
byte[] pemPrime1 = (keySize1024 ? new byte[64] : new byte[128]);
Array.Copy(keyData, index, pemPrime1, 0, pemPrime1.Length);
index += pemPrime1.Length;
index += (keySize1024 ? ((int)keyData[index + 1] == 64 ? 2 : 3) : ((int)keyData[index + 2] == 128 ? 3 : 4));
byte[] pemPrime2 = (keySize1024 ? new byte[64] : new byte[128]);
Array.Copy(keyData, index, pemPrime2, 0, pemPrime2.Length);
index += pemPrime2.Length;
index += (keySize1024 ? ((int)keyData[index + 1] == 64 ? 2 : 3) : ((int)keyData[index + 2] == 128 ? 3 : 4));
byte[] pemExponent1 = (keySize1024 ? new byte[64] : new byte[128]);
Array.Copy(keyData, index, pemExponent1, 0, pemExponent1.Length);
index += pemExponent1.Length;
index += (keySize1024 ? ((int)keyData[index + 1] == 64 ? 2 : 3) : ((int)keyData[index + 2] == 128 ? 3 : 4));
byte[] pemExponent2 = (keySize1024 ? new byte[64] : new byte[128]);
Array.Copy(keyData, index, pemExponent2, 0, pemExponent2.Length);
index += pemExponent2.Length;
index += (keySize1024 ? ((int)keyData[index + 1] == 64 ? 2 : 3) : ((int)keyData[index + 2] == 128 ? 3 : 4));
byte[] pemCoefficient = (keySize1024 ? new byte[64] : new byte[128]);
Array.Copy(keyData, index, pemCoefficient, 0, pemCoefficient.Length);
RSAParameters para = new RSAParameters();
para.Modulus = pemModulus;
para.Exponent = pemPublicExponent;
para.D = pemPrivateExponent;
para.P = pemPrime1;
para.Q = pemPrime2;
para.DP = pemExponent1;
para.DQ = pemExponent2;
para.InverseQ = pemCoefficient;
return para;
}
#endregion
#region 根据PEM格式公钥生成C#可识别的格式
/// <summary>
/// 根据PEM格式公钥生成C#可识别的格式
/// </summary>
/// <param name="publicKeyString"></param>
/// <returns></returns>
public static RSACryptoServiceProvider CreateRsaProviderFromPublicKey(string publicKeyString)
{
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
RSAParameters RSAKeyInfo = ConvertFromPemPublicKey(publicKeyString);
RSA.ImportParameters(RSAKeyInfo);
return RSA;
}
/// <summary>
/// 将pem格式公钥(1024 or 2048)转换为RSAParameters
/// </summary>
/// <param name="publicKeyString">pem公钥内容</param>
/// <returns>转换得到的RSAParamenters</returns>
public static RSAParameters ConvertFromPemPublicKey(string publicKeyString)
{
if (string.IsNullOrEmpty(publicKeyString))
{
throw new ArgumentNullException("pemFileConent", "This arg cann't be empty.");
}
byte[] keyData = Convert.FromBase64String(publicKeyString);
bool keySize1024 = (keyData.Length == 162);
bool keySize2048 = (keyData.Length == 294);
if (!(keySize1024 || keySize2048))
{
throw new ArgumentException("pem file content is incorrect, Only support the key size is 1024 or 2048");
}
byte[] pemModulus = (keySize1024 ? new byte[128] : new byte[256]);
byte[] pemPublicExponent = new byte[3];
Array.Copy(keyData, (keySize1024 ? 29 : 33), pemModulus, 0, (keySize1024 ? 128 : 256));
Array.Copy(keyData, (keySize1024 ? 159 : 291), pemPublicExponent, 0, 3);
RSAParameters para = new RSAParameters();
para.Modulus = pemModulus;
para.Exponent = pemPublicExponent;
return para;
}
public static bool CompareBytearrays(byte[] a, byte[] b)
{
if (a.Length != b.Length)
return false;
int i = 0;
foreach (byte c in a)
{
if (c != b[i])
return false;
i++;
}
return true;
}
#endregion
/// <summary>
/// 字符串签名
/// </summary>
/// <param name="_privateKey">私钥</param>
/// <param name="_signStr">待签名的字符串</param>
/// <returns>签名后的结果</returns>
public static string Sign(string _privateKey, string _signStr)
{
byte[] bytes = new UTF8Encoding().GetBytes(_signStr);
string basestr = Convert.ToBase64String(bytes);
string strEncryptedSignatureData = string.Empty;
try
{
byte[] HashData = GetMD5HashCode(basestr);
RSACryptoServiceProvider provider = DecodeRSAPrivateKey(_privateKey);
byte[] EncryptedSignatureData;
RSAPKCS1SignatureFormatter RSAFormatter = new RSAPKCS1SignatureFormatter(provider);
//设置签名的算法为MD5
RSAFormatter.SetHashAlgorithm("MD5");
//执行签名
EncryptedSignatureData = RSAFormatter.CreateSignature(HashData);
strEncryptedSignatureData = Convert.ToBase64String(EncryptedSignatureData);
return strEncryptedSignatureData;
}
catch (Exception ex)
{
throw ex;
}
}
/// <summary>
/// 获取MD5 HASH值
/// </summary>
/// <param name="_base64Str">UTF8格式Base64字符串</param>
/// <returns></returns>
public static byte[] GetMD5HashCode(string _base64Str)
{
byte[] Buffer;
try
{
System.Security.Cryptography.HashAlgorithm MD5 = System.Security.Cryptography.HashAlgorithm.Create("MD5");
Buffer = System.Text.Encoding.UTF8.GetBytes(_base64Str);
return MD5.ComputeHash(Buffer);
}
catch (Exception e)
{
throw e;
}
}
/// <summary>
/// RSA签名验证
/// </summary>
/// <param name="_publicKey"></param>
/// <param name="_plainStr"></param>
/// <param name="_strEncryptedSignatureData"></param>
/// <returns></returns>
public static bool Verify(string _publicKey, string _plainStr, string _strEncryptedSignatureData)
{
try
{
byte[] bytes = new UTF8Encoding().GetBytes(_plainStr);
string basestr = Convert.ToBase64String(bytes);
byte[] HashData = GetMD5HashCode(basestr);
RSACryptoServiceProvider provider = CreateRsaProviderFromPublicKey(_publicKey);
RSAPKCS1SignatureDeformatter RSADeformatter = new RSAPKCS1SignatureDeformatter(provider);
//指定解密的时候HASH算法为MD5
RSADeformatter.SetHashAlgorithm("MD5");
if (RSADeformatter.VerifySignature(HashData, Convert.FromBase64String(_strEncryptedSignatureData)))
{
return true;
}
else
{
return false;
}
}
catch (Exception ex)
{
throw ex;
}
}
/// <summary>
/// 获取字符串MD5值
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static string GetMD5HashFromString(string str)
{
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
byte[] bytValue, bytHash;
bytValue = System.Text.Encoding.UTF8.GetBytes(str);
bytHash = md5.ComputeHash(bytValue);
md5.Clear();
string sTemp = "";
for (int i = 0; i < bytHash.Length; i++)
{
sTemp += bytHash[i].ToString("X").PadLeft(2, '0');
}
return sTemp.ToUpper();
}
}
}
浙公网安备 33010602011771号