RSA生成公钥私解加密码解密数据的原理理解及应用思路.

二话不说,先上一个图:

 

如上图所示

第一步:左边是服务器端,右边是客户端,先通过RSA算法生成两组公私钥,分别给服务器和客户端.

第二步:然后服务器端与客户端分别交互各自的公钥,各自保管好自己的私钥不要泄露.

第三步:每次要与服务端交互数据时,都先通过公钥加密,每次接收到数据之后先通过私钥解密.以保证数据的安全性.

 

来一段RSA生成公钥及私钥,加密及解密的公共类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

 

namespace WebAPI.Tools
{
    /// <summary>
    /// RSA 非对称加解密算法
    /// </summary>
    public class RSAHelper
    {
        private int MAXENCRYPTSIZE = 117;
        private int MAXDECRYPTSIZE = 128;

 

        public string priKeyXml
        {
            get;
            private set;
        }

 

        public string pubKeyXml
        {
            get;
            private set;
        }

 


        private RSAHelper(string privateKey, string publicKey)
        {
            this.priKeyXml = privateKey;
            this.pubKeyXml = publicKey;
        }

 

        public static RSAHelper Load(string privateKey = "", string publicKey = "")
        {
            if (string.IsNullOrEmpty(privateKey) && string.IsNullOrEmpty(publicKey))
            {
                //无key时生成新密钥
                return Instance;
            }
            return new RSAHelper(privateKey, publicKey);
        }

 

        /// <summary>
        /// 随机生成公私钥并返回对象
        /// </summary>
        public static RSAHelper Instance
        {
            get
            {
                RSACryptoServiceProvider provider = new RSACryptoServiceProvider(1024);
                var publicKeyXml = provider.ToXmlString(false);
                //publickey:<RSAKeyValue><Modulus>w9u2HfdbNZrmAUmXPbNmrhfy861qX4mzcCn69Ksl03Nz+Fq9gINZeN/vrfcWBzMyYxb2/J2TnGtpCLc0ls6gOTKDPbnQHwHr3oCzfvxNwvT2uoKQUBl4xMFw0TmvufMbheq6q3FCXUkVkAUC1cbQ/S9DqNp/veYcAavRDXtFdD0=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>
                var privateKeyXml = provider.ToXmlString(true);
                //privatekey:<RSAKeyValue><Modulus>w9u2HfdbNZrmAUmXPbNmrhfy861qX4mzcCn69Ksl03Nz+Fq9gINZeN/vrfcWBzMyYxb2/J2TnGtpCLc0ls6gOTKDPbnQHwHr3oCzfvxNwvT2uoKQUBl4xMFw0TmvufMbheq6q3FCXUkVkAUC1cbQ/S9DqNp/veYcAavRDXtFdD0=</Modulus><Exponent>AQAB</Exponent><P>6tzaLZmY+hLLAifunWwcdUSfqTUvKOO5bJ8M1Zt34en40tfBaH9zml9gP8cmXaWyfpiZgHlPS9xlkLngudAiJw==</P><Q>1Xw2E1ufXsCM2JZahB6PH9pCgfD4XPjrqxF9xOWVvfbPmVBZByBIHYRs8ifbjIPvSKuaCfVFVStoIcOYrT9I+w==</Q><DP>mS4iPsuHMtM/BND2mEYC6ZkwaTP+5jRgo6+4tzkHH5lyaFHAG1/FDlJWfEJvi3SezmLI+zojtd6xf4s8PvS40Q==</DP><DQ>I91kMEhaM87hWpmXx05i+RTvy2iyMNxYqzqbCHMRfwJxye3npvzTYLIYo23ywl5/2pOJo1ajOTW7nsB/a8uP9Q==</DQ><InverseQ>EtYQvvBViXf7A5bgh+H4xLlBezD0yziBigoP/xcg1mcuI9Kb9rtPq64hQsajDYeNmm0Ibkxz9ihHr8+uWtdi5w==</InverseQ><D>HSivw2RZKvDlv1lSb/gumEqufALcbF7W3SMS3qxAVGvC3z27Ks/jWTCVwWOg3u+LV99KZC+dk1MWbxq/dJhMmBSiHOT6Sg7wvNMmX58zHl7Bhs702henzbr7CkiWrUcy3pVigr4olT9FlkjQkeEu9VfVW4TRGUDUkixTeh9MMC0=</D></RSAKeyValue>

 

                return new RSAHelper(privateKeyXml, publicKeyXml);
            }
        }

 

 

 

        /// <summary>
        /// RSA公钥加密
        /// </summary>
        /// <param name="content"></param>
        /// <param name="publicKeyXml">公钥xml串</param>
        /// <returns></returns>
        public string Encrypt(string content)
        {
            //string publickey = @"<RSAKeyValue><Modulus>w9u2HfdbNZrmAUmXPbNmrhfy861qX4mzcCn69Ksl03Nz+Fq9gINZeN/vrfcWBzMyYxb2/J2TnGtpCLc0ls6gOTKDPbnQHwHr3oCzfvxNwvT2uoKQUBl4xMFw0TmvufMbheq6q3FCXUkVkAUC1cbQ/S9DqNp/veYcAavRDXtFdD0=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
            byte[] cipherbytes;
            rsa.FromXmlString(pubKeyXml);
            cipherbytes = rsa.Encrypt(Encoding.UTF8.GetBytes(content), false);

 

            return Convert.ToBase64String(cipherbytes);
            //return cipherbytes;
        }
        /// <summary> 
        /// RSA私钥解密 
        /// </summary> 
        /// <param name="encryptData">经过Base64编码的密文</param> 
        /// <param name="privateKeyXml">私钥xml串</param> 
        /// <returns>RSA解密后的数据</returns> 
        public string Decrypt(string encryptData)
        {
            string decryptData = "";
            try
            {
                RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
                provider.FromXmlString(priKeyXml);
                byte[] bEncrypt = Convert.FromBase64String(encryptData);
                int length = bEncrypt.Length;
                int offset = 0;
                string cache;
                int i = 0;
                while (length - offset > 0)
                {
                    if (length - offset > MAXDECRYPTSIZE)
                    {
                        var aa = GetSplit(bEncrypt, offset, MAXDECRYPTSIZE);
                        cache = Encoding.UTF8.GetString(provider.Decrypt(aa, false));
                    }
                    else
                    {
                        var aa = GetSplit(bEncrypt, offset, length - offset);
                        cache = Encoding.UTF8.GetString(provider.Decrypt(aa, false));
                    }
                    decryptData += cache;
                    i++;
                    offset = i * MAXDECRYPTSIZE;
                }
            }
            catch (Exception e)
            {
                throw e;
            }
            return decryptData;
        }

 

        /// <summary>
        /// RSA解密
        /// </summary>
        /// <param name="privatekey"></param>
        /// <param name="content"></param>
        /// <returns></returns>
        public string RSADecrypt(string content)
        {
            //privatekey = @"<RSAKeyValue><Modulus>5m9m14XH3oqLJ8bNGw9e4rGpXpcktv9MSkHSVFVMjHbfv+SJ5v0ubqQxa5YjLN4vc49z7SVju8s0X4gZ6AzZTn06jzWOgyPRV54Q4I0DCYadWW4Ze3e+BOtwgVU1Og3qHKn8vygoj40J6U85Z/PTJu3hN1m75Zr195ju7g9v4Hk=</Modulus><Exponent>AQAB</Exponent><P>/hf2dnK7rNfl3lbqghWcpFdu778hUpIEBixCDL5WiBtpkZdpSw90aERmHJYaW2RGvGRi6zSftLh00KHsPcNUMw==</P><Q>6Cn/jOLrPapDTEp1Fkq+uz++1Do0eeX7HYqi9rY29CqShzCeI7LEYOoSwYuAJ3xA/DuCdQENPSoJ9KFbO4Wsow==</Q><DP>ga1rHIJro8e/yhxjrKYo/nqc5ICQGhrpMNlPkD9n3CjZVPOISkWF7FzUHEzDANeJfkZhcZa21z24aG3rKo5Qnw==</DP><DQ>MNGsCB8rYlMsRZ2ek2pyQwO7h/sZT8y5ilO9wu08Dwnot/7UMiOEQfDWstY3w5XQQHnvC9WFyCfP4h4QBissyw==</DQ><InverseQ>EG02S7SADhH1EVT9DD0Z62Y0uY7gIYvxX/uq+IzKSCwB8M2G7Qv9xgZQaQlLpCaeKbux3Y59hHM+KpamGL19Kg==</InverseQ><D>vmaYHEbPAgOJvaEXQl+t8DQKFT1fudEysTy31LTyXjGu6XiltXXHUuZaa2IPyHgBz0Nd7znwsW/S44iql0Fen1kzKioEL3svANui63O3o5xdDeExVM6zOf1wUUh/oldovPweChyoAdMtUzgvCbJk1sYDJf++Nr0FeNW1RB1XG30=</D></RSAKeyValue>";
            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
            byte[] cipherbytes;
            rsa.FromXmlString(priKeyXml);
            cipherbytes = rsa.Decrypt(Convert.FromBase64String(content), false);
            return Encoding.UTF8.GetString(cipherbytes);
        }

        /// <summary> 
        /// 截取字节数组部分字节 
        /// </summary> 
        /// <param name="input"></param> 
        /// <param name="offset">起始偏移位</param> 
        /// <param name="length">截取长度</param> 
        /// <returns></returns> 
        private byte[] GetSplit(byte[] input, int offset, int length)
        {
            byte[] output = new byte[length];
            for (int i = offset; i < offset + length; i++)
            {
                output[i - offset] = input[i];
            }
            return output;
        }
    }
}

 

通过WebAPI中调用生成公钥及私钥的方法:

        /// <summary>
        /// 通过Post获取公钥和私钥
        /// </summary>
        /// <returns>返回两对RSA公钥和私钥</returns>
        public UserRSAFile Post(string username)
        {
            UserRSAFile rsaFile = new UserRSAFile();
            rsaFile.username = username;

           //生成客户端的公钥和私钥
            RSAHelper rhelp = RSAHelper.Load();
            TestEncDesMod mod = new TestEncDesMod();
            mod.PrivateKeyForServer = false;
            mod.PublicKey = rhelp.pubKeyXml;
            mod.PrivateKey = rhelp.priKeyXml;
            rsaFile.ClientRSA = mod;
            //生成服务器端的公钥和私钥
            rhelp = RSAHelper.Load();
            mod = new TestEncDesMod();
            mod.PrivateKeyForServer = false;
            mod.PublicKey = rhelp.pubKeyXml;
            mod.PrivateKey = rhelp.priKeyXml;
            rsaFile.ServerRSA = mod;
            return rsaFile;
        }

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值