zoukankan      html  css  js  c++  java
  • 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;
            }
    
        }
  • 相关阅读:
    认识AppDomain类
    认识Math类
    控制输入法
    开发中常见错误
    flash视频窗口被关闭卡住了父窗口
    TransactionScope 事务 net2.0
    发现system.collection 命名空间下面的类大部分是基于数组来存储
    utf8 编码出现空白
    如何WEB上的消息提醒
    当前不会命中断点
  • 原文地址:https://www.cnblogs.com/localhost2016/p/8668489.html
Copyright © 2011-2022 走看看