zoukankan      html  css  js  c++  java
  • C#通过安全证书生成签名和验签辅助类

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Net;
    using System.Security.Cryptography;
    using System.Security.Cryptography.X509Certificates;
    using System.Text;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    namespace TestEPS
    {
        public static class bangzhu
        {
          private static string prikeyPath = "D:\testMer.key.der";
          private static string pubkeyPath = "D:\testUmpay.cert.crt";
            //private static string prikeyPath = @"E:证书地址.der";
            //private static string pubkeyPath = @"E:证书.crt";
            //用私钥生成签名
            public static string sign(string unsign)
            {
                string prikey = DecodeDERKey(prikeyPath);
                RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
                try
                {
                    rsa.FromXmlString(prikey);
                }
                catch (Exception ex)
                {
                    return "";
                }
                // 加密对象 
                RSAPKCS1SignatureFormatter f = new RSAPKCS1SignatureFormatter(rsa);
                f.SetHashAlgorithm("SHA1");
                //把要签名的源串转化成字节数组
                byte[] source = System.Text.UnicodeEncoding.Default.GetBytes(unsign);
                SHA1Managed sha = new SHA1Managed();
                //对签名源串做哈昔算法,为sha1.
                byte[] result = sha.ComputeHash(source);
                string s = Convert.ToBase64String(result);
                Console.WriteLine(s);
                //对哈昔算法后的字符串进行签名.
                byte[] b = f.CreateSignature(result);
                //生长签名对象sign
                string sign = Convert.ToBase64String(b);
                return sign;
            }
            //用公钥进行签名的验证
            public static bool verify(string unsign, string sign)
            {
                string pubkey = pathToXMLKey(pubkeyPath);
                RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
                rsa.FromXmlString(pubkey);
                //实例化验签对象.
                RSAPKCS1SignatureDeformatter f2 = new RSAPKCS1SignatureDeformatter(rsa);
                //设置哈昔算法为sha1
                f2.SetHashAlgorithm("SHA1");
                //把签名串转化为字节数组
                byte[] key = Convert.FromBase64String(sign);
                SHA1Managed sha2 = new SHA1Managed();
                //计算源串的哈昔值,生成字节数组.
                byte[] name = sha2.ComputeHash(System.Text.UnicodeEncoding.Default.GetBytes(unsign));
                //通过字节数组生成哈昔值
                string s2 = Convert.ToBase64String(name);
                Console.WriteLine(s2);
                return f2.VerifySignature(name, key);
            }
            //  获取der格式的私钥,转化成xml格式的私钥.
            private static string DecodeDERKey(String filename)
            {
                string xmlprivatekey = null;
                RSACryptoServiceProvider rsa = null;
                byte[] keyblob = GetFileBytes(filename);
                if (keyblob == null)
                    xmlprivatekey = "";
                rsa = DecodeRSAPrivateKey(keyblob);
                if (rsa != null)
                {
                    xmlprivatekey = rsa.ToXmlString(true);
                }
                return xmlprivatekey;
            }
            //------- Parses binary ans.1 RSA private key; returns RSACryptoServiceProvider  ---
            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
                BinaryReader binr = new BinaryReader(mem, Encoding.ASCII);
                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 -----
                    RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
                    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)
                {
                    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) //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.PeekChar() == 0x00)
                { //remove high order zeros in data
                    binr.ReadByte();
                    count -= 1;
                }
                return count;
            }
            private static byte[] GetFileBytes(String filename)
            {
                if (!File.Exists(filename))
                    return null;
                Stream stream = new FileStream(filename, FileMode.Open);
                int datalen = (int)stream.Length;
                byte[] filebytes = new byte[datalen];
                stream.Seek(0, SeekOrigin.Begin);
                stream.Read(filebytes, 0, datalen);
                string str = System.Text.Encoding.ASCII.GetString(filebytes);
                stream.Close();
                return filebytes;
            }
            //从x509格式的证书中,提取公钥,并转换成xml格式
            private static string pathToXMLKey(string pubkeyPath)
            {
                X509Certificate cert = null;
                try
                { // Try loading certificate as binary DER into an X509Certificate object.
                    cert = X509Certificate.CreateFromCertFile(pubkeyPath);
                }
                catch (System.Security.Cryptography.CryptographicException)
                { //not binary DER; try BASE64 format
                    StreamReader sr = File.OpenText(pubkeyPath);
                    String filestr = sr.ReadToEnd();
                    sr.Close();
                    StringBuilder sb = new StringBuilder(filestr);
                    sb.Replace("-----BEGIN CERTIFICATE-----", "");
                    sb.Replace("-----END CERTIFICATE-----", "");
                    try
                    {        //see if the file is a valid Base64 encoded cert
                        byte[] certBytes = Convert.FromBase64String(sb.ToString());
                        cert = new X509Certificate(certBytes);
                    }
                    catch (System.FormatException)
                    {
                        Console.WriteLine("Not valid binary DER or Base64 X509 certificate format");
                        return null;
                    }
                    catch (System.Security.Cryptography.CryptographicException)
                    {
                        Console.WriteLine("Not valid binary DER or Base64 X509 certificate format");
                        return null;
                    }
                }  // end outer catch
                string xmlpublickey = null;
                byte[] modulus, exponent;
                byte[] rsakey = cert.GetPublicKey();
                // ---------  Set up stream to read the asn.1 encoded SubjectPublicKeyInfo blob  ------
                MemoryStream mem = new MemoryStream(rsakey);
                BinaryReader binr = new BinaryReader(mem);
                ushort twobytes = 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();
                    byte lowbyte = 0x00;
                    byte highbyte = 0x00;
                    if (twobytes == 0x8102) //data read as little endian order (actual data order for Integer is 02 81)
                        lowbyte = binr.ReadByte(); // read next bytes which is bytes in modulus
                    else if (twobytes == 0x8202)
                    {
                        highbyte = binr.ReadByte(); //advance 2 bytes
                        lowbyte = binr.ReadByte();
                    }
                    else
                        return null;
                    byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };   //reverse byte order since asn.1 key uses big endian
                    int modsize = BitConverter.ToInt32(modint, 0);
                    int firstbyte = binr.PeekChar();
                    if (firstbyte == 0x00)
                    { //if first byte (highest order) of modulus is zero, don't include it
                        binr.ReadByte(); //skip this null byte
                        modsize -= 1; //reduce modulus buffer size by 1
                    }
                    modulus = binr.ReadBytes(modsize); //read the modulus bytes
                    if (binr.ReadByte() != 0x02) //expect an Integer for the exponent data
                        return null;
                    int expbytes = (int)binr.ReadByte(); // should only need one byte for actual exponent data
                    exponent = binr.ReadBytes(expbytes);
                    if (binr.PeekChar() != -1) // if there is unexpected more data, then this is not a valid asn.1 RSAPublicKey
                        return null;
                    // ------- create RSACryptoServiceProvider instance and initialize with public key   -----
                    RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
                    RSAParameters RSAKeyInfo = new RSAParameters();
                    RSAKeyInfo.Modulus = modulus;
                    RSAKeyInfo.Exponent = exponent;
                    rsa.ImportParameters(RSAKeyInfo);
                    xmlpublickey = rsa.ToXmlString(false);
                    return xmlpublickey;
                }
                catch (Exception)
                {
                    return null;
                }
                finally
                {
                    binr.Close();
                }
            }
        }
    }
  • 相关阅读:
    cmd中输入vue ui不起作用
    win10下如何让别人访问自己的数据库,开放3306端口
    maven出现报错:Failed to execute goal on project ***** Could not resolve dependencies for project com.**.**.**:jar:0.0.1-SNAPSHOT: Could not find artifact:jar:1.0-SNAPSHOT -> [Help 1]
    vue中改变字体大小,px不起作用
    vue安装教程
    Springboot快速入门
    【POI】Excel数据导入
    【MySQL】替换件需求
    【Git】Gitlab仓库访问拒绝,SSL校验影响
    【MySQL】java.sql.SQLException: Illegal mix of collations (utf8mb4_0900_ai_ci,IMPLICIT) and (utf8mb4_general_ci,IMPLICIT) for operation '='
  • 原文地址:https://www.cnblogs.com/dullbaby/p/5553108.html
Copyright © 2011-2022 走看看