using System;
using System.Security.Cryptography;
using System.Text;
namespace SignNameSpace
{
public class SignClass
{
//Base64编码
public string SignBase64Fomate()
{
string signStr = "abc123";
var encoding = Encoding.GetEncoding("UTF-8");
string Sign = Convert.ToBase64String(encoding.GetBytes(signStr));
return Sign; //YWJjMTIz
}
//Base64解码
public string DecodeBase64Fomate()
{
string signStr = "YWJjMTIz";
var encoding = Encoding.GetEncoding("UTF-8");
string decode = "";
byte[] bytes = Convert.FromBase64String(signStr);
decode = encoding.GetString(bytes);
return decode;
}
}
}
二、HMACSHA1
using System;
using System.Security.Cryptography;
using System.Text;
namespace SignNameSpace
{
public class SignClass
{
//HMACSHA1
public string SignHMACSHA1Fomate()
{
string signStr = "abc123";
string key = "456"; //密钥
var encoding = Encoding.GetEncoding("UTF-8");
var hmacsha1 = new HMACSHA1(encoding.GetBytes(key));
byte[] hashBytes = hmacsha1.ComputeHash(encoding.GetBytes(signStr));
string Sign = BitConverter.ToString(hashBytes).Replace("-", "").ToLower(); //签名后转小写
return Sign; //de4cbb63e690f2d18fa5e15d400f7608203dd863
}
}
}
三、Md5
using System;
using System.Security.Cryptography;
using System.Text;
namespace SignNameSpace
{
public class SignClass
{
//Md5
public string SignMd5Fomate()
{
string signStr = "abc123";
var encoding = Encoding.GetEncoding("UTF-8");
MD5CryptoServiceProvider md5Hasher = new MD5CryptoServiceProvider();
byte[] Md5data = md5Hasher.ComputeHash(encoding.GetBytes(signStr));
string Sign = BitConverter.ToString(Md5data).Replace("-", "").ToLower(); //签名后转小写
return Sign; //e99a18c428cb38d5f260853678922e03
}
}
}
四、BytesTohexString、HexStringToBytes
using System;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.IO;
namespace SignNameSpace
{
public class SignClass
{
public static string BytesTohexString(byte[] bytes)
{
if (bytes == null || bytes.Count() < 1)
{
return string.Empty;
}
var count = bytes.Count();
var cache = new StringBuilder();
//cache.Append("0x");
for (int ii = 0; ii < count; ++ii)
{
var tempHex = Convert.ToString(bytes[ii], 16).ToUpper();
cache.Append(tempHex.Length == 1 ? "0" + tempHex : tempHex);
}
return cache.ToString();
}
public static byte[] HexStringToBytes(string hexStr)
{
if (string.IsNullOrEmpty(hexStr))
{
return new byte[0];
}
if (hexStr.StartsWith("0x"))
{
hexStr = hexStr.Remove(0, 2);
}
var count = hexStr.Length;
if (count % 2 == 1)
{
throw new ArgumentException("Invalid length of bytes:" + count);
}
var byteCount = count / 2;
var result = new byte[byteCount];
for (int ii = 0; ii < byteCount; ++ii)
{
var tempBytes = Byte.Parse(hexStr.Substring(2 * ii, 2), System.Globalization.NumberStyles.HexNumber);
result[ii] = tempBytes;
}
return result;
}
}
}
五、SHA1withRSA加密,验证
using System;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.IO;
namespace SignNameSpace
{
public class SignClass
{
public SignClass()
{
//说明:
//1.私钥和公钥的生成是具有对应关系的, 如果私钥和公钥不对应,且用以加解密,则Verify会验证失败。
//2.生成RSA私钥和公钥工具,可使用支付宝RSA工具,https://docs.open.alipay.com/291/105971/
//3.私钥和公钥生成过程中,注意是否是java版,或非java版
//4.生成RSA私钥和公钥工具使用方法参见:
//私钥加密
var privateKey = "MIICXgIBAAKBgQCO772dmiRP4HaddeZTUieS4SWrNnbRPIgxoF5wLZNK1nel3hf7uffWkZ5lzjSuLig5sgPzU/oQgophIG9+NwoHeyXPgnhNV8zPluueHFrQzrSnq9jhUS1yxTezmYr+oxAQIyGQUZO21Sg1+2lqDyatPpRfN4JSKusAw9yOcbkHKQIDAQABAoGAArchNgZAnFfaSQF9X6XW5J5sVcVSGoV43OB8CsuC2dAbM8Z1VC3jPGtFxA9XxttPnlD4bD3zKS8hq9iu5YnsIdL7bt1hu2vOW2UGtIPfYtTMK49BcgYHk1zIlQh21Jt403SM0hDmbpy/R32QQ3cv5jWnVvlEqiULyOC0joe9vTUCQQDAv4dOl3v3HQ40cWoe7RUKqbn0bBM4xIx2fwMBJTMJFJFWBq97CwtvuwKnlWle5dRDLTrwt7rETfNPW898nb3jAkEAvdeci8MLDAQE9KeIyxJK1170ahwkxTcO8miI5o/u6AekWk+YuNJh871YKoxwqPtD/2cDQH3PLxwklvVJExJ0gwJBAJ7QcP1ZpcPLxfuCA21t7St3A4gYUJIyqIWuS1xzOSTfNI0MPySDyi2KijpoyoRtnEKpjunuiM3caIDX5hMIqf8CQQCfFzYoZa43RpMEl/VqAI1ZiUiYN7eU0fwjpvi7Bvm11tmjmTqqABx4Dz/4gDLVWaP1P9WY0RW0LAh5vVqcsgWTAkEAk27NKkvwGR37bcHF2QwxeQkY+5pamJhIGvEm+dbhOm9P1mmcujrfZ49Aegy3RiIBQACHRNgjC6sYZcrs/wPrXw==";
var sres = sign("A1b", privateKey, "UTF-8");
//公钥解密
var publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCO772dmiRP4HaddeZTUieS4SWrNnbRPIgxoF5wLZNK1nel3hf7uffWkZ5lzjSuLig5sgPzU/oQgophIG9+NwoHeyXPgnhNV8zPluueHFrQzrSnq9jhUS1yxTezmYr+oxAQIyGQUZO21Sg1+2lqDyatPpRfN4JSKusAw9yOcbkHKQIDAQAB";
var vres = verify("A1b", sres, publicKey, "UTF-8");
}
///
/// SHA1withRSA签名
///
/// 待签名字符串
/// 私钥
/// 编码格式
/// 签名后字符串
public static string sign(string content, string privateKey, string input_charset)
{
try
{
byte[] Data = Encoding.GetEncoding(input_charset).GetBytes(content);
RSACryptoServiceProvider rsa = DecodePemPrivateKey(privateKey);
using (var sh = SHA1.Create())
{
byte[] signData = rsa.SignData(Data, sh);
return Convert.ToBase64String(signData); //结果进行base64编码,也可以转其他格式
}
}
catch { return ""; }
}
///
/// 公钥验签
///
/// 待验签字符串
/// 签名
/// 公钥
/// 编码格式
/// true(通过),false(不通过)
public static bool Verify(string content, string signedString, string publicKey, string input_charset)
{
try
{
bool result = false;
byte[] Data = Encoding.GetEncoding(input_charset).GetBytes(content);
byte[] data = Convert.FromBase64String(signedString); //结果进行base64解码
RSAParameters paraPub = ConvertFromPublicKey(publicKey);
RSACryptoServiceProvider rsaPub = new RSACryptoServiceProvider();
rsaPub.ImportParameters(paraPub);
using (var sh = SHA1.Create())
{
result = rsaPub.VerifyData(Data, sh, data);
return result;
}
}
catch { return false; }
}
#region 内部方法
private static RSACryptoServiceProvider DecodePemPrivateKey(String pemstr)
{
RSACryptoServiceProvider rsa = DecodeRSAPrivateKey(Convert.FromBase64String(pemstr));
return rsa;
}
private static RSACryptoServiceProvider DecodeRSAPrivateKey(byte[] privkey)
{
byte[] MODULUS, E, D, P, Q, DP, DQ, IQ;
// --------- Set up stream to decode the asn.1 encoded RSA private key ------
MemoryStream mem = new MemoryStream(privkey);
BinaryReader binr = new BinaryReader(mem); //wrap Memory Stream with BinaryReader for easy reading
byte bt = 0;
ushort twobytes = 0;
int elems = 0;
try
{
twobytes = binr.ReadUInt16();
if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81)
binr.ReadByte(); //advance 1 byte
else if (twobytes == 0x8230)
binr.ReadInt16(); //advance 2 bytes
else
return null;
twobytes = binr.ReadUInt16();
if (twobytes != 0x0102) //version number
return null;
bt = binr.ReadByte();
if (bt != 0x00)
return null;
//------ all private key components are Integer sequences ----
elems = GetIntegerSize(binr);
MODULUS = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
E = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
D = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
P = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
Q = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
DP = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
DQ = binr.ReadBytes(elems);
elems = GetIntegerSize(binr);
IQ = binr.ReadBytes(elems);
// ------- create RSACryptoServiceProvider instance and initialize with public key -----
CspParameters CspParameters = new CspParameters();
CspParameters.Flags = CspProviderFlags.UseMachineKeyStore;
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(1024, CspParameters);
RSAParameters RSAparams = new RSAParameters();
RSAparams.Modulus = MODULUS;
RSAparams.Exponent = E;
RSAparams.D = D;
RSAparams.P = P;
RSAparams.Q = Q;
RSAparams.DP = DP;
RSAparams.DQ = DQ;
RSAparams.InverseQ = IQ;
RSA.ImportParameters(RSAparams);
return RSA;
}
catch
{
return null;
}
finally
{
binr.Dispose();
}
}
private static int GetIntegerSize(BinaryReader binr)
{
byte bt = 0;
byte lowbyte = 0x00;
byte highbyte = 0x00;
int count = 0;
bt = binr.ReadByte();
if (bt != 0x02) //expect integer
return 0;
bt = binr.ReadByte();
if (bt == 0x81)
count = binr.ReadByte(); // data size in next byte
else
if (bt == 0x82)
{
highbyte = binr.ReadByte(); // data size in next 2 bytes
lowbyte = binr.ReadByte();
byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };
count = BitConverter.ToInt32(modint, 0);
}
else
{
count = bt; // we already have the data size
}
while (binr.ReadByte() == 0x00)
{ //remove high order zeros in data
count -= 1;
}
binr.BaseStream.Seek(-1, SeekOrigin.Current); //last ReadByte wasn't a removed zero, so back up a byte
return count;
}
#endregion
#region 解析.net 生成的Pem
private static RSAParameters ConvertFromPublicKey(string publicKey)
{
if (string.IsNullOrEmpty(publicKey))
{
throw new ArgumentNullException("pemFileConent", "This arg cann't be empty.");
}
byte[] keyData = Convert.FromBase64String(publicKey);
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;
}
#endregion
}
}