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. bsp STEP

    Web开发不仅现在比较流行,将来也会.我来谈一下最近bsp  application项目的体会吧,属初学者,请各位多多指教. SAP 的web开发方法有很多种,bsp只是其中一种,而bsp开发有可以分 ...

  2. 【Android】配置APK开发环境

    1.安装java jdk去oracle公司下载jdk-7u15-windows-i586.exehttp://www.oracle.com/technetwork/cn/java/javase/dow ...

  3. 黑马程序员——【Java高新技术】——反射机制

    ---------- android培训.java培训.期待与您交流! ---------- 一.概述 1.Java反射机制:是指“在运行状态中”,对于任意一个类,都能够知道这个类中的所有属性和方法: ...

  4. AMQP与RabbitMQ简介

    MQ(Message Queue,消息队列)是一种应用系统之间的通信方法.是通过读写出入队列的消息来通信(RPC则是通过直接调用彼此来通信的). 1.AMQP协议 在了解RabbitMQ之前,首先要了 ...

  5. CSS缩放函数, 旋转函数与倾斜函数

       1 :缩放        scale(x,y)函数让元素根据中心原点对对象进行缩放,大于1进行放大,小于1则缩小,如果为负值,则先进行翻转再进行缩放操作. 实例: HTML: <div c ...

  6. WampServe修改默认网站目录的方法(转)

    1wamp简介 WampServe集成了Apache.MySQL.PHP.phpmyadmin,支持Apache的mod_rewrite,PHP扩展.Apache模块只需要在菜单“开启/关闭”上点点就 ...

  7. Android 学习第2课,下载 eclipse 工具

    可以到http://www.ddooo.com/softdown/61745.htm 下载下来是32位与64位都有的 而且是汉化的,经测试成功,还可以,不错!

  8. LintCode Search For a Range (Binary Search)

    Binary Search模板: mid 和 target 指针比较,left/ right 和 target 比较. 循环终止条件: 最后剩两数比较(while(left + 1 < righ ...

  9. C语言基本数据类型

    一.数据类型与“模子” short.int.long.char.float.double 这六个关键字代表C 语言里的六种基本数据类型. 怎么去理解它们呢? 举个例子:见过藕煤球的那个东西吧?(没见过 ...

  10. 《C与指针》第九章练习

    本章问题 1.C语言缺少显示的字符串数据类型,这是一个优点还是一个缺点? answer: (这个问题存在争论(尽管我有一个结论))目前这个方法的优点是字符数组的效率和访问的灵活性,它的缺点是有可能引起 ...