.Net AES、RSA 加密解密

          2019就这样过完了,2019的支付宝账单出来了,好像还有很多事情没来得及做,然后就过去了,整的还有很多遗憾,把握住2020的每一天时间吧,望你们的2020年不要浑浑噩噩,要忙忙碌碌、基础、学习、创新、记录、总结、生活都要前进向前看。过程重要结果更重要,不希望N年之后想想之前怎么不努力,薪水怎么不加,这些都是有原因的, 机遇都是给准备着的人的,总感觉这句话有问题,我时刻都准备着呢,机遇咋就是不给我,证明我还是不够努力不够上进呗。加油吧 小姑娘你的人生还很长,驾照还没考,更好的美食还没吃,薪水还没加,钱包还没满,世界各地去的还少,闺蜜还没嫁    、花呗还没还、房子还没买、车还没买,这么多还没做完的事情,你有什么不努力的,你家是富二代吗,并不是,现实帕帕 打脸,不闲聊了,项目上对接的新需求,下面就跟大家说一下 对接的心酸,怎么说呢,给银行那边要个密钥都慢的要死,直到现在还没全盘测试下来,不过加密解密这块总是跑通了,不容易啊,银行之前那边没有对接关于 .Net技术的,所以也没什么Demo给我,给的Java版的Demo,我硬着头皮看了一下流程,还算可以在此过程中也问了不少的大佬,感觉感谢大佬指点,,现在认为最难熬最困难的事情,你是潜在心里的怕,在此告诫 你尽管去 尝试、尽管去做、大胆,只要你行动付出,一定有收获有结果,过程中也遇到很多坑,不自觉并不想的跳进去,然后 时间证明 你一定会从坑中出来,而且是闪闪发光的你。这会自信心满满的了,等遇到问题就有没信心了,其实都是这样,只不过过程是你真实行动了,然后就会给你一个满意的答复,下面的第三方  指的是我,我(第三方)给 银行两个公钥,一个公钥一个签名公钥,用自己(第三方)签名私钥生成签名,银行里给的公钥加密,用银行里给的签名公钥验签,感觉我用语言描述不清楚,还是请各位大佬看下面的图 行事吧

阅读了很多关于RSA随机填充算法种类,包括NoPadding、ISO10126Padding、OAEPPadding、PKCS1Padding、PKCS5Padding、SSL3Padding,OAEPPadding、PKCS1Padding等。才找到和Java中的Cipher.getInstance("RSA/ECB/NoPadding", "BC") 一样通用的算法,当然这个过程也是不容易的,浪费了好几天的时间,一开始看并没有查到开源的,以为要自己写一个了呢,想想都一身冷汗,然后 现实并没有孤立我的付出,现在就和前辈们分享一下,传入的参数是描述为产生某种输出而在给定的输入上执行的操作(或一组操作)的字符串。必须包括加密算法的名称,后面可能跟有一个反馈模式和填充方案。这样的实现就比较灵活,我们可以通过参数指定不同的反馈模式和填充方案;

     C#采用的RSACryptoServiceProvider类进行的加解密,由于该类默认是不支持私钥加密公钥解密的,需要通过BouncyCastle.Crypto.dll转换一下才可以,在官网http://www.bouncycastle.org/csharp/ 下载最新dll。设置Cipher为“RSA/ECB/NoPadding,与Java对接平台一致。嗯 还有一点传送时一定要编码,否则可能会识别错误或者对方无法解密,编码:System.Web.HttpUtility.UrlEncode,在AES验签的时候是用的对方的公钥,出现了一次    "填充无效,无法被移除",出现这个问题的第一反映就是  咦,哪里写错了? 然后仔细检查,发现并没有什么问题,但是一直验签失败,到最后的问题居然是对接方(银行)给的签名公钥不对,纠正过来然后就验签成功了。如果加密、签名都成功了,然后解密、验签就是过不去的时候 一定要 "先跟对接方对一下"你给他们或者他们给你的公钥 私钥是不是一对。这个很重要,不要在这里浪费时间 ,由于我的不自信在这里浪费了好长时间,这里有告诉我一个道理,我是对的,就是对的,对的让我怀疑 人生。嗯 好的 那今天就先到这里,

 Java给的公钥、私钥不能直接是用,需要转换一下

密钥格式:


私钥:
<RSAKeyValue> 
<Modulus>pJlJIR0+G/vs7mhycs0Zd5DbWokMCsLX7Ih373+ljlteRmTm8IHj0Sl8zA26Qu/oAmqh9OFk806zW3TXl90RghSeQhzZBXFHBrTFN4U/o3wPhZBdFazh80bbskrmQ/jmz70qUm3HmGzsb3tox
zN6Ehakdo7qP2Kc6aOVTyXrYpk=</Modulus> 
<Exponent>AQAB</Exponent> 
<P>1WKkFg6jlS2eZSVLiH1CK4b9uhr7qE1/L+tPqKQs+PzHX4eiZXnyAlQ+kgGmL7n1wR1RWNuiYnDZUetmTogaDQ==</P> 
<Q>xXhsuEnNJNQcQHEVTPZoulbMbTV1VZIDQ1zjG8fvu8sv6IBYcR5+EsC8n3/6RkW8/iCJDzxE++VHzhoSQSoDvQ==</Q> 
<DP>zr/rcn+umd0Aisnu/Ik48smxz39TdIfaAwkBPsoL1Re+6V2WyLG1/fG4SmmUpsuMRRdt+SWdmbnzpr7peo++hQ==</DP> 
<DQ>MWi2W04sBEEGaKFi4QTuo2FAeTrdBvIn2t0M/lCCjYyDijtC5drpVKvhBk+xQZAFf9iIMsWzxQtTciBX3PI0SQ==</DQ> 
<InverseQ>wGEfA3LWM4NHgRnXDqwwOUs3OtqWK0tsJPPcFMci+Bcgy96JpFTCr7bubXHMu14bdopCWUann2d3UuwEpvP+</InverseQ> 
<D>mK3TRtMwRJb33OGnn9OeFumYfy92qxi3X6Hq1o6qDBW2qkd4bImfv+ni6AinyOVuaadt2Y+lq4dKGcCVJzoZvPm1VKxD2y7xKa8/vEbPRiRTt0qnPq9T7UJkpDsiXf/zOMfWdjc3uA1bPnQ65RWHS
J7zAE+Gd7xnyCE5MEyijLE=</D> 
</RSAKeyValue> 

公钥:
<RSAKeyValue> 
<Modulus>pJlJIR0+G/vs7mhycs0Zd5DbWokMCsLX7Ih373+ljlteRmTm8IHj0Sl8zA26Qu/oAmqh9OFk806zW3TXl90RghSeQhzZBXFHBrTFN4U/o3wPhZBdFazh80bbskrmQ/jmz70qUm3HmGzsb3tox
zN6Ehakdo7qP2Kc6aOVTyXrYpk=</Modulus> 
<Exponent>AQAB</Exponent>

 颜色相同的代表一对公私钥,本图涉及到四套证书,浅绿浅粉块的是自己的两套证书,浅黄浅蓝第三方证书。

需要引用类库:BouncyCastle.Crypto.dll

链接:https://pan.baidu.com/s/1F4dRJqTelI-NGQFXEGd94g
提取码:kuj5

RSA加密

/// <summary>
        /// RSA 公钥加密
        /// </summary>
        /// <param name="xmlPublicteKey">公钥</param>
        /// <param name="encryptKey">随机生成的Key</param>
        /// <returns></returns>
        public static string RSAEncryptByPublicteKey( string encryptKey)
        {
            RSACryptoServiceProvider publicRsa = new RSACryptoServiceProvider();
            publicRsa.FromXmlString(xmlPublicteKey);
            RSAParameters rp = publicRsa.ExportParameters(false);

            //转换密钥
            AsymmetricKeyParameter pbk = DotNetUtilities.GetRsaPublicKey(rp);
            IBufferedCipher c = CipherUtilities.GetCipher("RSA/ECB/NoPadding");// 参数与Java中加密解密的参数一致     //RSA/ECB/PKCS1Padding
            //第一个参数为true表示加密,为false表示解密;第二个参数表示密钥
            c.Init(true, pbk); //keyPair.Private

            byte[] DataToEncrypt = Encoding.UTF8.GetBytes(encryptKey);
            byte[] outBytes = c.DoFinal(DataToEncrypt);//加密
            string strBase64 = Convert.ToBase64String(outBytes);

            return strBase64;
        }
View Code

RSA解密

/// <summary>
        /// 私钥解密
        /// </summary>
        /// <param name="xmlPrivateKey"></param>
        /// <param name="encryptKey"></param>
        /// <returns></returns> 
        public static string RSAEncryptByPrivateKey( string encryptKey)
        {
            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
            rsa.FromXmlString(xmlPrivateKey);
            RSAParameters rp = rsa.ExportParameters(true);

            //转换密钥
            AsymmetricCipherKeyPair pbk = DotNetUtilities.GetRsaKeyPair(rp);
            IBufferedCipher c = CipherUtilities.GetCipher("RSA/ECB/NoPadding");// 参数与Java中加密解密的参数一致     
            //RSA/ECB/PKCS1Padding
            //第一个参数为true表示加密,为false表示解密;第二个参数表示密钥
            c.Init(false, pbk.Private); //keyPair.Private

            byte[] PlainTextBArray = Convert.FromBase64String(encryptKey);
            byte[] outBytes = c.DoFinal(PlainTextBArray);//加密
            string outresp = System.Text.UTF8Encoding.UTF8.GetString(outBytes);

            return outresp;
        }
View Code

AES加密

/// <summary>
        /// AES加密 
        /// </summary>
        /// <param name="text">加密字符</param>
        /// <param name="password">加密的密码</param>
        /// <returns></returns>
        public static string AESEncrypt(string text, string password)
        {
            RijndaelManaged rijndaelCipher = new RijndaelManaged();
            rijndaelCipher.Mode = CipherMode.ECB;
            rijndaelCipher.Padding = PaddingMode.PKCS7;
            rijndaelCipher.KeySize = 128;
            rijndaelCipher.BlockSize = 128;
            byte[] pwdBytes = System.Text.Encoding.UTF8.GetBytes(password);
            byte[] keyBytes = new byte[16];
            int len = pwdBytes.Length;
            if (len > keyBytes.Length) len = keyBytes.Length;
            System.Array.Copy(pwdBytes, keyBytes, len);
            rijndaelCipher.Key = keyBytes;
            byte[] ivBytes = System.Text.Encoding.GetEncoding("UTF-8").GetBytes("0102030405060708");
            rijndaelCipher.IV = new byte[16];
            ICryptoTransform transform = rijndaelCipher.CreateEncryptor();
            byte[] plainText = Encoding.UTF8.GetBytes(text);
            byte[] cipherBytes = transform.TransformFinalBlock(plainText, 0, plainText.Length);
            return Convert.ToBase64String(cipherBytes);

        }
View Code

AES解密

/// <summary>
        /// AES解密
        /// </summary>
        /// <param name="text"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        public static string AESDecrypt(string text, string password)
        {

            RijndaelManaged rijndaelCipher = new RijndaelManaged();
            rijndaelCipher.Mode = CipherMode.ECB;
            rijndaelCipher.Padding = PaddingMode.PKCS7;
            rijndaelCipher.KeySize = 128;
            rijndaelCipher.BlockSize = 128;
            byte[] pwdBytes = System.Text.Encoding.UTF8.GetBytes(password);
            byte[] keyBytes = new byte[16];
            int len = pwdBytes.Length;
            if (len > keyBytes.Length) len = keyBytes.Length;
            System.Array.Copy(pwdBytes, keyBytes, len);
            rijndaelCipher.Key = keyBytes;
            byte[] ivBytes = System.Text.Encoding.GetEncoding("UTF-8").GetBytes("0102030405060708");
            rijndaelCipher.IV = new byte[16];
            ICryptoTransform transform = rijndaelCipher.CreateDecryptor();
            //byte[] plainText = Encoding.UTF8.GetBytes(text);
            byte[] plainText = Convert.FromBase64String(text);
            byte[] cipherBytes = transform.TransformFinalBlock(plainText, 0, plainText.Length);
            return Encoding.UTF8.GetString(cipherBytes);

        }
View Code
原文地址:https://www.cnblogs.com/BabyRui/p/12168642.html