欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

使用SHA256来签名和验签.netcore详解

程序员文章站 2022-04-11 17:49:58
...

生成证书:

运行PowerShell:

makecert -r -pe -n "CN=IdentityServer Company" -b 01/01/2005 -e 01/01/2020 -sky exchange -a sha256 -len 2048 -ss my 

运行MMC:导出私钥和公钥

使用SHA256来签名和验签.netcore详解

使用SHA256来签名和验签.netcore详解

使用SHA256来签名和验签.netcore详解

使用SHA256来签名和验签.netcore详解

导出private.pfx 成功。

再导出公钥:

使用SHA256来签名和验签.netcore详解

导出公钥成功 public.cer 

新建.net core 3.0 项目:SHA256Demo

Nuge:

System.Security.Cryptography.Cng (4.6.0)

拷贝到项目:cer 目录下 

使用SHA256来签名和验签.netcore详解

Program.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;

namespace SHA256Demo
{
    class Program
    {
        static void Main(string[] args)
        {
            var priKeyFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "cer/private.pfx");
            var pubKeyFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "cer/public.cer");

            var contentForSign = "name=123&sex=boy";
            var keyPwd = "123456";

            var signedData = Sign(contentForSign, priKeyFile, keyPwd);

            var verifyResult = VerifySign(contentForSign, signedData, pubKeyFile);

            Console.WriteLine("Hello World!");
        }

        private static string Sign(string contentForSign, string priKeyFile, string keyPwd)
        {
            var rsa = GetPrivateKey(priKeyFile, keyPwd);
            // Create a new RSACryptoServiceProvider 
            var rsaClear = new RSACryptoServiceProvider();
            // Export RSA parameters from 'rsa' and import them into 'rsaClear' 
            var paras = rsa.ExportParameters(true);
            rsaClear.ImportParameters(paras);
            var signData = rsa.SignData(Encoding.UTF8.GetBytes(contentForSign), HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
            return BytesToHex(signData);
        }

        private static bool VerifySign(string contentForSign, string signedData, string pubKeyFile)
        {
            var rsa = GetPublicKey(pubKeyFile);
            return rsa.VerifyData(Encoding.UTF8.GetBytes(contentForSign), HexToBytes(signedData), HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
        }

        /// <summary> 
        /// 获取签名证书私钥 
        /// </summary> 
        /// <param name="priKeyFile"></param> 
        /// <param name="keyPwd"></param> 
        /// <returns></returns> 
        private static RSACng GetPrivateKey(string priKeyFile, string keyPwd)
        {
            var pc = new X509Certificate2(priKeyFile, keyPwd, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet);
            return (RSACng)pc.PrivateKey;
        }

        /// <summary> 
        /// 获取验签证书 
        /// </summary> 
        /// <param name="pubKeyFile"></param> 
        /// <returns></returns> 
        private static RSACng GetPublicKey(string pubKeyFile)
        {
            var pc = new X509Certificate2(pubKeyFile);
            return (RSACng)pc.PublicKey.Key;
        }

        public static byte[] HexToBytes(string text)
        {
            if (text.Length % 2 != 0)
                throw new ArgumentException("text 长度为奇数。");

            List<byte> lstRet = new List<byte>();
            for (int i = 0; i < text.Length; i = i + 2)
            {
                lstRet.Add(Convert.ToByte(text.Substring(i, 2), 16));
            }
            return lstRet.ToArray();
        }

        /// <summary> 
        /// bytes转换hex 
        /// </summary> 
        /// <param name="data">bytes</param> 
        /// <returns>转换后的hex字符串</returns> 
        public static string BytesToHex(byte[] data)
        {
            StringBuilder sbRet = new StringBuilder(data.Length * 2);
            for (int i = 0; i < data.Length; i++)
            {
                sbRet.Append(Convert.ToString(data[i], 16).PadLeft(2, '0'));
            }
            return sbRet.ToString();
        }
    }
}

 运行效果:

使用SHA256来签名和验签.netcore详解