RSA 数字签名算法(.net版)
直接上代码,不BB
public class RSASign { public static string RSASignature(string data, string privateKeyPem, string charset, bool keyFromFile, string signType) { byte[] signatureBytes = null; try { RSACryptoServiceProvider rsaCsp = null; if (keyFromFile) {//文件读取 rsaCsp = LoadCertificateFile(privateKeyPem, signType); } else { //字符串获取 rsaCsp = LoadCertificateString(privateKeyPem, signType); } byte[] dataBytes = null; if (string.IsNullOrEmpty(charset)) { dataBytes = Encoding.UTF8.GetBytes(data); } else { dataBytes = Encoding.GetEncoding(charset).GetBytes(data); } if (null == rsaCsp) { throw new Exception("您使用的私钥格式错误" + ",charset = " + charset); } if ("RSA2".Equals(signType)) { signatureBytes = rsaCsp.SignData(dataBytes, "SHA256"); } else { signatureBytes = rsaCsp.SignData(dataBytes, "SHA1"); } } catch (Exception ex) { throw new Exception("您使用的私钥格式错误" + ",charset = " + charset); } return Convert.ToBase64String(signatureBytes); } private static RSACryptoServiceProvider LoadCertificateFile(string filename, string signType) { using (System.IO.FileStream fs = System.IO.File.OpenRead(filename)) { byte[] data = new byte[fs.Length]; byte[] res = null; fs.Read(data, 0, data.Length); if (data[0] != 0x30) { res = GetPem("RSA PRIVATE KEY", data); } try { RSACryptoServiceProvider rsa = DecodeRSAPrivateKey(res, signType); return rsa; } catch (Exception ex) { } return null; } } private static byte[] GetPem(string type, byte[] data) { string pem = Encoding.UTF8.GetString(data); string header = String.Format("-----BEGIN {0}-----\\n", type); string footer = String.Format("-----END {0}-----", type); int start = pem.IndexOf(header) + header.Length; int end = pem.IndexOf(footer, start); string base64 = pem.Substring(start, (end - start)); return Convert.FromBase64String(base64); } private static RSACryptoServiceProvider LoadCertificateString(string strKey, string signType) { byte[] data = null; data = Convert.FromBase64String(strKey); try { RSACryptoServiceProvider rsa = DecodeRSAPrivateKey(data, signType); return rsa; } catch { } return null; } private static RSACryptoServiceProvider DecodeRSAPrivateKey(byte[] privkey, string signType) { byte[] MODULUS, E, D, P, Q, DP, DQ, IQ; MemoryStream mem = new MemoryStream(privkey); BinaryReader binr = new BinaryReader(mem); byte bt = 0; ushort twobytes = 0; int elems = 0; try { twobytes = binr.ReadUInt16(); if (twobytes == 0x8130) binr.ReadByte(); else if (twobytes == 0x8230) binr.ReadInt16(); else return null; twobytes = binr.ReadUInt16(); if (twobytes != 0x0102) return null; bt = binr.ReadByte(); if (bt != 0x00) return null; 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); CspParameters CspParameters = new CspParameters(); CspParameters.Flags = CspProviderFlags.UseMachineKeyStore; int bitLen = 1024; if ("RSA2".Equals(signType)) { bitLen = 2048; } RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(bitLen, 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(Exception ex) { return null; } finally { binr.Close(); } } private static int GetIntegerSize(BinaryReader binr) { byte bt = 0; byte lowbyte = 0x00; byte highbyte = 0x00; int count = 0; bt = binr.ReadByte(); if (bt != 0x02) return 0; bt = binr.ReadByte(); if (bt == 0x81) count = binr.ReadByte(); else if (bt == 0x82) { highbyte = binr.ReadByte(); lowbyte = binr.ReadByte(); byte[] modint = { lowbyte, highbyte, 0x00, 0x00 }; count = BitConverter.ToInt32(modint, 0); } else { count = bt; } while (binr.ReadByte() == 0x00) { count -= 1; } binr.BaseStream.Seek(-1, SeekOrigin.Current); return count; } }