C#.NET Framework 使用BC库(BouncyCastle) RSA 私钥签名 公钥验签(验证签名) ver:20230704
时间:2023-07-05 07:56:44来源:博客园

C#.NET Framework 使用BC库(BouncyCastle) RSA 私钥签名 公钥验签(验证签名) ver:20230704

环境说明:

.NET Framework 4.6 的控制台程序。


【资料图】

2020年以后 ,有部分PKCS8私钥(openssl生成)无法用RsaUtil.LoadPrivateKey(strPriPkcs8,"PKCS8")来解析(https://www.cnblogs.com/runliuv/p/17474269.html)

可以尝试用BC库来处理。

用“支付宝开放平台开发助手”生成一组公私钥:

PKCS8私钥:

MIICeQIBADANBgkqhkiG9w0BAQEFAASCAmMwggJfAgEAAoGBAMz0Czg6QUtTISa2pUkloeQB/TEpHdqrfyroWpKLW9B/LWFSOGH9nyTk1pPZaeadyEZQ6gay/C0pUAetLraq9bMA/Luxq68b87uG7WX7dKytEO2/87qGpGMRs97H+GlkzWil2QO2KK4cHnAcVicPsmi5aZ72U0BWJFyPhtd+qdmrAgMBAAECgYEAvW67iAbgHt0BASVD9C3iSjpEaVHVlC165o/IVzaTcEx8Bz3Ve0zN8W3JnvIO3ebsG4HiLLr2Nk++9rltOc0eNeGMv7F1e/OFot1wN0ON6s1g4bYh1z5Uz8FcYiMWcqHHICrx+oSFeK9x+I2Zge7enQXcsVnqEhm77ZE5YczSryECQQD9nB58e5efYchF+cYbmURioX18cUMuhQbB9Aq2N55cd689Lg35KZqT8JQTp/8tQSdCJG8d2nU8VKspUKTEAuaDAkEAzuKIIoc9PVJvy90LhIPA9c1S8BPCI7EMCaTZqJ5o3VaR2dqvUZDGX7kL3kYkQ+n7mq3KIECvkEFzA+FOP96XuQJBAJQTKHW0T/YeSKoayUHp/lS8R6F2HCy4PRbXn71+wfbpZqcJEd2OHhQM3tiPOV258esbjMlYeSUNppZL4LgVnXMCQQC7Lvs9Ql+GPDAqo7ToEM1lmICR906QPIBHuX+1sJ3wpYMROWumwPa7ZRH36j6ls+6R5OwcgmpWeuE1gYTrBNsBAkEAn2pEtAljX1foQff6CLozYg/J6J9RmVFcJ6qz0LX3052qNFBQYw8CMHB7VkVNzsDIDC8LX5uP2pzTrdPLew+pPA==

与之匹配的 PKCS1 私钥,用助手转换的:

MIICXwIBAAKBgQDM9As4OkFLUyEmtqVJJaHkAf0xKR3aq38q6FqSi1vQfy1hUjhh/Z8k5NaT2WnmnchGUOoGsvwtKVAHrS62qvWzAPy7sauvG/O7hu1l+3SsrRDtv/O6hqRjEbPex/hpZM1opdkDtiiuHB5wHFYnD7JouWme9lNAViRcj4bXfqnZqwIDAQABAoGBAL1uu4gG4B7dAQElQ/Qt4ko6RGlR1ZQteuaPyFc2k3BMfAc91XtMzfFtyZ7yDt3m7BuB4iy69jZPvva5bTnNHjXhjL+xdXvzhaLdcDdDjerNYOG2Idc+VM/BXGIjFnKhxyAq8fqEhXivcfiNmYHu3p0F3LFZ6hIZu+2ROWHM0q8hAkEA/ZwefHuXn2HIRfnGG5lEYqF9fHFDLoUGwfQKtjeeXHevPS4N+Smak/CUE6f/LUEnQiRvHdp1PFSrKVCkxALmgwJBAM7iiCKHPT1Sb8vdC4SDwPXNUvATwiOxDAmk2aieaN1Wkdnar1GQxl+5C95GJEPp+5qtyiBAr5BBcwPhTj/el7kCQQCUEyh1tE/2HkiqGslB6f5UvEehdhwsuD0W15+9fsH26WanCRHdjh4UDN7YjzldufHrG4zJWHklDaaWS+C4FZ1zAkEAuy77PUJfhjwwKqO06BDNZZiAkfdOkDyAR7l/tbCd8KWDETlrpsD2u2UR9+o+pbPukeTsHIJqVnrhNYGE6wTbAQJBAJ9qRLQJY19X6EH3+gi6M2IPyeifUZlRXCeqs9C199OdqjRQUGMPAjBwe1ZFTc7AyAwvC1+bj9qc063Ty3sPqTw=

与之匹配的公钥:

MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDM9As4OkFLUyEmtqVJJaHkAf0xKR3aq38q6FqSi1vQfy1hUjhh/Z8k5NaT2WnmnchGUOoGsvwtKVAHrS62qvWzAPy7sauvG/O7hu1l+3SsrRDtv/O6hqRjEbPex/hpZM1opdkDtiiuHB5wHFYnD7JouWme9lNAViRcj4bXfqnZqwIDAQAB

关键代码:

BC库,私钥转换,默认支持PKCS8:

private static AsymmetricKeyParameter GetPrivateKeyParameter(string privateKeyPem)        {            //获取私钥纯字符串            privateKeyPem = privateKeyPem.Replace("-----BEGIN RSA PRIVATE KEY-----", "").Replace("-----END RSA PRIVATE KEY-----", "").Replace("\r", "").Replace("\n", "").Trim();            privateKeyPem = privateKeyPem.Replace("-----BEGIN PRIVATE KEY-----", "").Replace("-----END PRIVATE KEY-----", "").Replace("\r", "").Replace("\n", "").Trim();            byte[] privateInfoByte = Convert.FromBase64String(privateKeyPem);            AsymmetricKeyParameter priKey = PrivateKeyFactory.CreateKey(privateInfoByte);            return priKey;        }

公钥转换:

private static AsymmetricKeyParameter GetPublicKeyParameter(string publicKeyPem)        {            //获取公钥纯字符串            publicKeyPem = publicKeyPem.Replace("-----BEGIN PUBLIC KEY-----", "").Replace("-----END PUBLIC KEY-----", "").Replace("\r", "").Replace("\n", "").Trim();            byte[] publicInfoByte = Convert.FromBase64String(publicKeyPem);            AsymmetricKeyParameter pubKey = PublicKeyFactory.CreateKey(publicInfoByte);            return pubKey;        }

BCSignUtil 辅助类,nuget 中引用Portable.BouncyCastle。

using Org.BouncyCastle.Crypto;using Org.BouncyCastle.Security;using System;using System.Text;namespace CommonUtils{    public static class BCSignUtil    {        ///         /// 签名        ///         /// 原数据字符串        /// 必须是PKCS8的        /// 算法        ///         public static string SignData(string orgData, string privateKeyPKCS8, string algorithm)        {            if (string.IsNullOrEmpty(orgData))                throw new Exception("字符串不能为空!");            if (string.IsNullOrEmpty(privateKeyPKCS8))                throw new Exception("privateKeyPKCS8不能为空!");            if (string.IsNullOrEmpty(privateKeyPKCS8))                throw new Exception("algorithm 不能为空!");            AsymmetricKeyParameter priKey = GetPrivateKeyParameter(privateKeyPKCS8);            byte[] byteData = Encoding.UTF8.GetBytes(orgData);            ISigner normalSig = SignerUtilities.GetSigner(algorithm);            normalSig.Init(true, priKey);            normalSig.BlockUpdate(byteData, 0, byteData.Length);//注意:是byte数组和数组长度,别写成string的长度了            byte[] normalResult = normalSig.GenerateSignature(); //签名结果            string sign = Convert.ToBase64String(normalResult);            return sign;        }        private static AsymmetricKeyParameter GetPrivateKeyParameter(string privateKeyPem)        {            //获取私钥纯字符串            privateKeyPem = privateKeyPem.Replace("-----BEGIN RSA PRIVATE KEY-----", "").Replace("-----END RSA PRIVATE KEY-----", "").Replace("\r", "").Replace("\n", "").Trim();            privateKeyPem = privateKeyPem.Replace("-----BEGIN PRIVATE KEY-----", "").Replace("-----END PRIVATE KEY-----", "").Replace("\r", "").Replace("\n", "").Trim();            byte[] privateInfoByte = Convert.FromBase64String(privateKeyPem);            AsymmetricKeyParameter priKey = PrivateKeyFactory.CreateKey(privateInfoByte);            return priKey;        }        ///         /// 验证签名        ///         /// 原数据字符串        /// 公钥        /// 对方的签名串        /// 算法        ///         public static bool VerifySignature(string orgData, string publicKeyPem, string responseSign, string algorithm)        {            AsymmetricKeyParameter pubKey = GetPublicKeyParameter(publicKeyPem);            byte[] signBytes = Convert.FromBase64String(responseSign);            byte[] plainBytes = Encoding.UTF8.GetBytes(orgData);            ISigner verifier = SignerUtilities.GetSigner(algorithm);            verifier.Init(false, pubKey);            verifier.BlockUpdate(plainBytes, 0, plainBytes.Length);//注意:是byte数组和数组长度,别写成string的长度了            bool isOK = verifier.VerifySignature(signBytes); //验签结果            return isOK;        }        private static AsymmetricKeyParameter GetPublicKeyParameter(string publicKeyPem)        {            //获取公钥纯字符串            publicKeyPem = publicKeyPem.Replace("-----BEGIN PUBLIC KEY-----", "").Replace("-----END PUBLIC KEY-----", "").Replace("\r", "").Replace("\n", "").Trim();            byte[] publicInfoByte = Convert.FromBase64String(publicKeyPem);            AsymmetricKeyParameter pubKey = PublicKeyFactory.CreateKey(publicInfoByte);            return pubKey;        }    }}

使用代码:

using CommonUtils;using System;namespace ConsoleNetFxRsa加密签名使用BC库{    class Program    {        static void Main(string[] args)        {            try            {                //PKCS8格式私钥                string strPriPkcs8 = "MIICeQIBADANBgkqhkiG9w0BAQEFAASCAmMwggJfAgEAAoGBAMz0Czg6QUtTISa2pUkloeQB/TEpHdqrfyroWpKLW9B/LWFSOGH9nyTk1pPZaeadyEZQ6gay/C0pUAetLraq9bMA/Luxq68b87uG7WX7dKytEO2/87qGpGMRs97H+GlkzWil2QO2KK4cHnAcVicPsmi5aZ72U0BWJFyPhtd+qdmrAgMBAAECgYEAvW67iAbgHt0BASVD9C3iSjpEaVHVlC165o/IVzaTcEx8Bz3Ve0zN8W3JnvIO3ebsG4HiLLr2Nk++9rltOc0eNeGMv7F1e/OFot1wN0ON6s1g4bYh1z5Uz8FcYiMWcqHHICrx+oSFeK9x+I2Zge7enQXcsVnqEhm77ZE5YczSryECQQD9nB58e5efYchF+cYbmURioX18cUMuhQbB9Aq2N55cd689Lg35KZqT8JQTp/8tQSdCJG8d2nU8VKspUKTEAuaDAkEAzuKIIoc9PVJvy90LhIPA9c1S8BPCI7EMCaTZqJ5o3VaR2dqvUZDGX7kL3kYkQ+n7mq3KIECvkEFzA+FOP96XuQJBAJQTKHW0T/YeSKoayUHp/lS8R6F2HCy4PRbXn71+wfbpZqcJEd2OHhQM3tiPOV258esbjMlYeSUNppZL4LgVnXMCQQC7Lvs9Ql+GPDAqo7ToEM1lmICR906QPIBHuX+1sJ3wpYMROWumwPa7ZRH36j6ls+6R5OwcgmpWeuE1gYTrBNsBAkEAn2pEtAljX1foQff6CLozYg/J6J9RmVFcJ6qz0LX3052qNFBQYw8CMHB7VkVNzsDIDC8LX5uP2pzTrdPLew+pPA==";                //PKCS1格式私钥                string strPriPkcs1 = "MIICXwIBAAKBgQDM9As4OkFLUyEmtqVJJaHkAf0xKR3aq38q6FqSi1vQfy1hUjhh/Z8k5NaT2WnmnchGUOoGsvwtKVAHrS62qvWzAPy7sauvG/O7hu1l+3SsrRDtv/O6hqRjEbPex/hpZM1opdkDtiiuHB5wHFYnD7JouWme9lNAViRcj4bXfqnZqwIDAQABAoGBAL1uu4gG4B7dAQElQ/Qt4ko6RGlR1ZQteuaPyFc2k3BMfAc91XtMzfFtyZ7yDt3m7BuB4iy69jZPvva5bTnNHjXhjL+xdXvzhaLdcDdDjerNYOG2Idc+VM/BXGIjFnKhxyAq8fqEhXivcfiNmYHu3p0F3LFZ6hIZu+2ROWHM0q8hAkEA/ZwefHuXn2HIRfnGG5lEYqF9fHFDLoUGwfQKtjeeXHevPS4N+Smak/CUE6f/LUEnQiRvHdp1PFSrKVCkxALmgwJBAM7iiCKHPT1Sb8vdC4SDwPXNUvATwiOxDAmk2aieaN1Wkdnar1GQxl+5C95GJEPp+5qtyiBAr5BBcwPhTj/el7kCQQCUEyh1tE/2HkiqGslB6f5UvEehdhwsuD0W15+9fsH26WanCRHdjh4UDN7YjzldufHrG4zJWHklDaaWS+C4FZ1zAkEAuy77PUJfhjwwKqO06BDNZZiAkfdOkDyAR7l/tbCd8KWDETlrpsD2u2UR9+o+pbPukeTsHIJqVnrhNYGE6wTbAQJBAJ9qRLQJY19X6EH3+gi6M2IPyeifUZlRXCeqs9C199OdqjRQUGMPAjBwe1ZFTc7AyAwvC1+bj9qc063Ty3sPqTw=";                //公钥                string strPub = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDM9As4OkFLUyEmtqVJJaHkAf0xKR3aq38q6FqSi1vQfy1hUjhh/Z8k5NaT2WnmnchGUOoGsvwtKVAHrS62qvWzAPy7sauvG/O7hu1l+3SsrRDtv/O6hqRjEbPex/hpZM1opdkDtiiuHB5wHFYnD7JouWme9lNAViRcj4bXfqnZqwIDAQAB";                string strDJM = "泰酷拉!123ABC";//待签名字符串                strDJM = "泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC";//待加密字符串,超过117字符的测试                Console.WriteLine("待签名字符串:" + strDJM);                                #region 一、私钥签名                //string algorithm = "SHA1withRSA";                string algorithm = "SHA256withRSA";                string strSigned = BCSignUtil.SignData(strDJM, strPriPkcs8, algorithm); //PKCS8                Console.WriteLine("签名值:" + strSigned);                #endregion                #region 二、公钥验签(验证签名)                //二、公钥验签(验证签名)                //验证签名                bool bCheck = BCSignUtil.VerifySignature(strDJM, strPub, strSigned, algorithm);//验证签名双方要保持一致                Console.WriteLine("验证签名:" + bCheck.ToString());                #endregion            }            catch (Exception ex)            {                Console.WriteLine("ex:" + ex.Message);            }            Console.WriteLine("hello END.");            Console.ReadKey();        }    }}

标签:

生活指南
  • 环球即时看!dnf的徽章镶嵌后还可以拿下来吗_dnf里面的徽章镶嵌在装备上以后还能取下来么

    1、dnf里面的徽章镶嵌在装备上以后不可以取下来了,证明方法为:首先找

  • 广东河源发生3.7级地震 广州、东莞等地有震感

    广东省河源市东源县于7月3日20时许发生3 7级地震。广州、东莞、梅州等

  • 下跌途中t字线说明了什么?T字倒T字双组合的深度解析-每日速看

    最近小编看到很多人在搜索​T字倒T字的相关内容,小编呢对此也是非

  • 中坝大峡谷是怎样的景区?中坝大峡谷景区有哪些景观?-全球动态

    中坝大峡谷是怎样的景区?石泉中坝大峡谷位于陕西省石泉县境内的汉

  • 金牛座的专属性格卡,你占几个?

    在金牛的世界里在面对自己的生活时也从来都不缺乏重头再来的勇气金牛座

  • 福蓉科技: 截至6月30日公司股东人数是17037 全球快播报

    福蓉科技(603327)07月03日在投资者关系平台上答复了投资者关心的问题。

  • 积极践行企业社会责任,中国平安连续21年荣获"中国最受尊敬企业"

    (平安产险湖北分公司供稿)12月29日,"2021-2022年度中国最受尊敬企业"

  • dnf租赁武器怎么租?DNF租赁武器位置分享

    dnf租赁武器怎么租?首先进入游戏,点击赛利亚房间的npc米娅里克特;

  • 环球速讯:雷雨大风强降水!黑龙江省发布强对流天气预报

    黑龙江省气象台2023年7月1日12时00分发布强对流预报:预计未来6小时,

  • 三星将于9月23日推出Galaxy S20粉丝版

    三星GalaxyS20风扇(FE)在9月23日正式发布之前就已经泄露了。几天前,泄

  • 深圳地铁19号线(关于深圳地铁19号线介绍)

    来为大家讲解以上的问题。深圳地铁19号线,圳地铁19号线介绍这个很多人

  • 手机相片放在哪个文件夹_手机如何给相片换底色

    你们好,最近小品发现有诸多的小伙伴们对于手机相片放在哪个文件夹,手

  • 沉香重华一天更新几集啊(沉香重华一天更新几集)

    《沉香重华》更新时间日历和《沉香如屑》一样,每周一到周三晚上8点更

  • 焦点观察:6月30日尾气治理板块涨幅达2%

    6月30日10点50分,尾气治理板块指数报1337 293点,涨幅达2%,成交23 46

  • 焦点!博格巴很可能在今年夏天离开尤文

    据报道,尤文希望在今年夏天卖掉博格巴,为转会筹集资金。在转会到曼联

  • 雍正为什么会等她去世后才动年羹尧?原因只有一点

    年羹尧是清朝历史上一位非常杰出的军事将领,传说他料事如神,指挥大军

  • 民生
    • 【新视野】7家券商上半年推出定增预案

    • 环球视点!国家统计局:6月下旬生猪(外三元)价格环比下降3.5%

    • 二季度全省政府网站、政务新媒体运行情况发布

    • 腾势N7摒弃无框车门:120km/h噪音遥遥领先特斯拉Model Y和极氪001|世界短讯