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();
            }
        }
    }
}

C#通过安全证书生成签名和验签辅助类的更多相关文章

  1. PHP SHA1withRSA加密生成签名及验签

    最近公司对接XX第三方支付平台的代付业务,由于对方公司只有JAVA的demo,所以只能根据文档自己整合PHP的签名加密,网上找过几个方法,踩到各种各样的坑,还好最后算是搞定了,话不多说,代码分享出来. ...

  2. 使用非对称算法RSA实现加解密和使用签名算法SHA1WithRSA、MD5withRSA生成签名以及验签

    不啰嗦,直接上源码 package com.hudai.platform.manager.util; import java.io.ByteArrayOutputStream; import java ...

  3. erlang的RSA签名与验签

    1.RSA介绍 RSA是目前最有影响力的公钥加密算法,该算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但那时想要对 其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥,即公钥,而 ...

  4. 几个例子理解对称加密与非对称加密、公钥与私钥、签名与验签、数字证书、HTTPS加密方式

    # 原创,转载请留言联系 为什么会出现这么多加密啊,公钥私钥啊,签名啊这些东西呢?说到底还是保证双方通信的安全性与完整性.例如小明发一封表白邮件给小红,他总不希望给别人看见吧.而各种各样的技术就是为了 ...

  5. .NET RSA解密、签名、验签

    using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Sec ...

  6. 中行P1签名及验签

    分享中国银行快捷.NET P1签名和验签方法代码中ReturnValue为自定义类型请无视 #region 验证签名 /// <summary> /// 验证签名 /// </sum ...

  7. RSA后台签名前台验签的应用(前台采用jsrsasign库)

    写在前面 安全测试需要, 为防止后台响应数据返给前台过程中被篡改前台再拿被篡改后的数据进行接下来的操作影响正常业务, 决定采用RSA对响应数据进行签名和验签, 于是有了这篇<RSA后台签名前台验 ...

  8. 密码基础知识(2)以RSA为例说明加密、解密、签名、验签

    密码基础知识(1)https://www.cnblogs.com/xdyixia/p/11528572.html 一.RSA加密简介 RSA加密是一种非对称加密.是由一对密钥来进行加解密的过程,分别称 ...

  9. RSA/RSA2 进行签名和验签

    package com.byttersoft.hibernate.erp.szmy.util; import java.io.ByteArrayInputStream; import java.io. ...

随机推荐

  1. pdf 显示

    昨天调用同事写好的显示pdf借口  他返回给我的byte 我这面进行接受流的时候  长度一直跟他的对应不上 最后用WebClient类进行解决 webclient类 第一种是将文件存储在文件系统上,用 ...

  2. IOS照片框架

    介绍 每天,用 iPhone 拍摄的照片数量超过了任何相机.每年 iOS 设备上的显示效果变得越来越好,回到 iPad 刚出现还没有 Retina 显示屏的时代,大屏幕的杀手级功能之一就是可以展示用户 ...

  3. Bower安装Bootstrap

    1.Bower简介 官网:https://bower.io/ Bower can manage components that contain HTML, CSS, JavaScript, fonts ...

  4. JQuery源码解析(十一)

    内存泄露 什么是内存泄露? 内存泄露是指一块被分配的内存既不能使用,又不能回收,直到浏览器进程结束.在C++中,因为是手动管理内存,内存泄露是经常出现的事情.而现在流行的C#和Java等语言采用了自动 ...

  5. kinnect相关

    1. kinnect的现状. http://tech.qq.com/a/20150909/046760.htm 2. kinnect的相关工作 http://baike.baidu.com/link? ...

  6. IIS32位,64位模式下切换

    一.32位模式 1.cscript %systemdrive%\inetpub\adminscripts\adsutil.vbs set w3svc/appPools/enable32bitappon ...

  7. Centos7.2 Systemd 方式编译 Mysql5.7.11

    导读 MySQL 5.7 版本的发布,也就是说从现在开始5.7已经可以在生产环境中使用,有任何问题官方都将立刻修复. MySQL 5.7主要特性: 原生支持Systemd 更好的性能:对于多核CPU. ...

  8. jquery.cookie() 方法的使用(读取、写入、删除)

    一个轻量级的cookie 插件,可以读取.写入.删除 cookie. jquery.cookie.js 的配置 首先包含jQuery的库文件,在后面包含 jquery.cookie.js 的库文件. ...

  9. Oracle学习系列7

    Oracle学习系列7 ************************************************************************************ 关联表 ...

  10. xampp 文件夹拷贝的注意事项。

    xampp可以同盘符拷贝,比如由A电脑的D:\XAMPP拷贝到B电脑的D:\XAMPP,此拷贝不用修改任何设置,当进行不同盘拷贝时,要修改apache和mysql下的一大堆conf文件,修改盘符: x ...