C#使用BouncyCastle来实现私钥加密公钥解密的方法与java互通的RSA加解密和签名(转)

摘要:
因为C#的RSA加密和解密只包括公钥加密和私钥解密。没有私钥加密和公钥解密。邦西城堡的文件很少。很多人可能会说C#也可以通过Biginteger开源类实现。然而,有一篇文章对十六进制结果进行了加密。它根本无法与JAVA通信。甚至加密结果的格式也与C#的原始加密结果不同。接下来,我继续寻找信息和方法。在线验证后发布。您可以进行DEMO,然后进行在线RSA加密和解密验证。

因为C#的RSA加密解密只有公钥加密,私钥解密,没有私钥加密,公钥解密。在网上查了很久也没有很好的实现。BouncyCastle的文档少之又少。很多人可能会说,C#也是可以的,通过Biginteger开源类来实现,不过那个是有一个文章,不过他加密出来的是16进制结果的。根本不能和JAVA互通。连加密出来的都不和C#原生的加密出来的结果格式一样。所以还是没有好的解决方法。

接下来还是不断的找资料,找方法。找朋友找同事。个个都找。问题是有的,方法也是有的,所以总结各路大神之后写了这个类。实现了私钥加密,公钥解密。并通过在线的校验之后,发布上来。大家可以做一个DEMO,然后进去在线RSA加密解密校验。

在线RSA,DES等加密解密地址:

http://tool.chacuo.net/cryptrsapubkey

可以直接nuget搜索BouncyCastle,安装即可

下面是代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Pkcs;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.X509;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Crypto.Encodings;
using System.IO;
namespace Tool
{
    public class RSATool
    {

        public RSATool()
        {

        }
        /// <summary>
        /// KEY 结构体
        /// </summary>
        public struct RSAKEY
        {
            /// <summary>
            /// 公钥
            /// </summary>
            public string PublicKey
            {
                get;
                set;
            }
            /// <summary>
            /// 私钥
            /// </summary>
            public string PrivateKey
            {
                get;
                set;
            }
        }
        public RSAKEY GetKey()
        {
            //RSA密钥对的构造器  
            RsaKeyPairGenerator keyGenerator = new RsaKeyPairGenerator();

            //RSA密钥构造器的参数  
            RsaKeyGenerationParameters param = new RsaKeyGenerationParameters(
                Org.BouncyCastle.Math.BigInteger.ValueOf(3),
                new Org.BouncyCastle.Security.SecureRandom(),
                1024,   //密钥长度  
                25);
            //用参数初始化密钥构造器  
            keyGenerator.Init(param);
            //产生密钥对  
            AsymmetricCipherKeyPair keyPair = keyGenerator.GenerateKeyPair();
            //获取公钥和密钥  
            AsymmetricKeyParameter publicKey = keyPair.Public;
            AsymmetricKeyParameter privateKey = keyPair.Private;

            SubjectPublicKeyInfo subjectPublicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicKey);
            PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateKey);


            Asn1Object asn1ObjectPublic = subjectPublicKeyInfo.ToAsn1Object();

            byte[] publicInfoByte = asn1ObjectPublic.GetEncoded("UTF-8");
            Asn1Object asn1ObjectPrivate = privateKeyInfo.ToAsn1Object();
            byte[] privateInfoByte = asn1ObjectPrivate.GetEncoded("UTF-8");

            RSAKEY item = new RSAKEY()
            {
                PublicKey = Convert.ToBase64String(publicInfoByte),
                PrivateKey = Convert.ToBase64String(privateInfoByte)
            };
            return item;
        }
        private AsymmetricKeyParameter GetPublicKeyParameter(string s)
        {
            s = s.Replace("
", "").Replace("
", "").Replace(" ", "");
            byte[] publicInfoByte = Convert.FromBase64String(s);
            Asn1Object pubKeyObj = Asn1Object.FromByteArray(publicInfoByte);//这里也可以从流中读取,从本地导入   
            AsymmetricKeyParameter pubKey = PublicKeyFactory.CreateKey(publicInfoByte);
            return pubKey;
        }
        private AsymmetricKeyParameter GetPrivateKeyParameter(string s)
        {
            s = s.Replace("
", "").Replace("
", "").Replace(" ", "");
            byte[] privateInfoByte = Convert.FromBase64String(s);
            // Asn1Object priKeyObj = Asn1Object.FromByteArray(privateInfoByte);//这里也可以从流中读取,从本地导入   
            // PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateKey);
            AsymmetricKeyParameter priKey = PrivateKeyFactory.CreateKey(privateInfoByte);
            return priKey;
        }
        public string EncryptByKey(string s, string key, bool isPublic)
        {
            //非对称加密算法,加解密用  
            IAsymmetricBlockCipher engine = new Pkcs1Encoding(new RsaEngine());
            //加密  
            try
            {
                engine.Init(true, isPublic ? GetPublicKeyParameter(key) : GetPrivateKeyParameter(key));
                byte[] byteData = System.Text.Encoding.UTF8.GetBytes(s);

                int inputLen = byteData.Length;
                MemoryStream ms = new MemoryStream();
                int offSet = 0;
                byte[] cache;
                int i = 0;
                // 对数据分段加密
                while (inputLen - offSet > 0)
                {
                    if (inputLen - offSet > 117)
                    {
                        cache = engine.ProcessBlock(byteData, offSet, 117);
                    }
                    else
                    {
                        cache = engine.ProcessBlock(byteData, offSet, inputLen - offSet);
                    }
                    ms.Write(cache, 0, cache.Length);
                    i++;
                    offSet = i * 117;
                }
                byte[] encryptedData = ms.ToArray();

                //var ResultData = engine.ProcessBlock(byteData, 0, byteData.Length);
                return Convert.ToBase64String(encryptedData);
                //Console.WriteLine("密文(base64编码):" + Convert.ToBase64String(testData) + Environment.NewLine);
            }
            catch (Exception ex)
            {
                return ex.Message;

            }
        }
        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="s"></param>
        /// <param name="key"></param>
        /// <param name="isPublic"></param>
        /// <returns></returns>
        public string DecryptByPublicKey(string s, string key, bool isPublic)
        {
            s = s.Replace("
", "").Replace("
", "").Replace(" ", "");
            //非对称加密算法,加解密用  
            IAsymmetricBlockCipher engine = new Pkcs1Encoding(new RsaEngine());


            //加密  

            try
            {
                engine.Init(false, isPublic ? GetPublicKeyParameter(key) : GetPrivateKeyParameter(key));
                byte[] byteData = Convert.FromBase64String(s);

                int inputLen = byteData.Length;
                MemoryStream ms = new MemoryStream();
                int offSet = 0;
                byte[] cache;
                int i = 0;
                // 对数据分段加密
                while (inputLen - offSet > 0)
                {
                    if (inputLen - offSet > 128)
                    {
                        cache = engine.ProcessBlock(byteData, offSet, 128);
                    }
                    else
                    {
                        cache = engine.ProcessBlock(byteData, offSet, inputLen - offSet);
                    }
                    ms.Write(cache, 0, cache.Length);
                    i++;
                    offSet = i * 128;
                }
                byte[] encryptedData = ms.ToArray();

                //var ResultData = engine.ProcessBlock(byteData, 0, byteData.Length);
                return Encoding.UTF8.GetString(ms.ToArray());
                //Console.WriteLine("密文(base64编码):" + Convert.ToBase64String(testData) + Environment.NewLine);
            }
            catch (Exception ex)
            {
                return ex.Message;

            }
        }
        /// <summary>
        /// 签名
        /// </summary>
        /// <param name="data">数据</param>
        /// <param name="key">密匙</param>
        /// <returns></returns>
        public string SignByPrivateKey(string data, string key)
        {
            AsymmetricKeyParameter priKey = GetPrivateKeyParameter(key);
            byte[] byteData = System.Text.Encoding.UTF8.GetBytes(data);

            ISigner normalSig = SignerUtilities.GetSigner("SHA1WithRSA");
            normalSig.Init(true, priKey);
            normalSig.BlockUpdate(byteData, 0, data.Length);
            byte[] normalResult = normalSig.GenerateSignature(); //签名结果
            return Convert.ToBase64String(normalResult);
            //return System.Text.Encoding.UTF8.GetString(normalResult);
        }

        /// <summary>
        /// 验签
        /// </summary>
        /// <param name="plainData">验证数据</param>
        /// <param name="sign">签名</param>
        /// <param name="key">公匙</param>
        /// <returns></returns>
        public bool ValidationPublicKey(string plainData, string sign, string key)
        {
            AsymmetricKeyParameter priKey = GetPublicKeyParameter(key);

            byte[] signBytes = Convert.FromBase64String(sign);
            byte[] plainBytes = Encoding.UTF8.GetBytes(plainData);


            ISigner verifier = SignerUtilities.GetSigner("SHA1WithRSA");
            verifier.Init(false, priKey);
            verifier.BlockUpdate(plainBytes, 0, plainBytes.Length);

            return verifier.VerifySignature(signBytes); //验签结果
        }
    }
}

  转自:https://www.cnblogs.com/AnAng/p/10396296.html

免责声明:文章转载自《C#使用BouncyCastle来实现私钥加密公钥解密的方法与java互通的RSA加解密和签名(转)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇第11章 PADS功能使用技巧(2)-最全面JKS和PKCS#12下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Springboot项目集成JPush极光推送(Java SDK)

1.由于项目的需求,需要在Android APP上实现消息推送功能,所以引用了极光推送(官网:https://www.jiguang.cn/,  文档:http://docs.jiguang.cn/) 2.极光推送是经过考验的大规模app推送平台,极光推送目前每天推送消息数超过20亿条。 开发者集成SDK后,可以通过调用API推送消息。同时,极光推送提供可...

C++ string 内存管理

String 是STL里面的类似一个字符串容器。 String对象调用append(),不能之家已有的字符串加大,因为相邻的内存可能被占用,因此需要分配一个新的内存块,将原来的内存赋值到新的内存块中。这样会降低效率。 所以c++实现分配了一个比实际字符串大的内存块,如果字符串不断增大,超过了内存块大小,程序将分配一个大小为原理两倍的新内存卡,以提高足够的空...

关于JavaScriptInterface的一系列问题

先明确主题,主要做了什么。 接手时app主体是混合开发,以elipse+android SDK为开发环境,但我是个渣渣,我只会用AS,就转成了AS,这部分等会新开文章写。 主要的view只有一个activity_main,里边写了个webview,在mainactivity里去掉了actionbar,一个导入库都没有有四个jar包,然后所有的HTML代码放...

Android ORM——初识greenDAO 3及使用greenDAO 3前应该掌握的一些知识点(一)

引言 总所周知,SQLite——内嵌于Android中一个占用内存极小的关系型,作为我们Android存储领域中重要的一员 ,或多或少都曾接触到数据库。即使Android系统中提供了很多操作SQLite的API,可是在业务开发中还是须要手动去编写原生SQL语句,这不仅复杂、不好维护。更重要的是不高效,经常会由于SQL语句写错而添加了开发成本,于是便出现...

Unity面试题汇总(第一部分)

一、什么是渲染管道? 答:就是告诉GPU一些数据,经过一系列的操作,得到最终要显示的数据。渲染管道中的很多步骤,总的来说是将几何物体从一个坐标系变换到另一个坐标系中去。 主要步骤如下: 本地坐标系 -- 经过世界变换矩阵 --> 世界坐标系 -- 经过视图变换矩阵 --> 视图坐标系 -- 经过投影变换矩阵 --> 投影坐标系 -- 经过...

微信开发——使用微信接口(获取地理位置)

生成微信签名(只要访问微信的接口,都需要生成签名验证来进行config) a. 获取AccessToken //定义静态常量存放获取AccessToken的URL public final static String GetPageAccessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?gra...