RSA加密算法

来源:互联网 发布:炉石大数据查询 编辑:程序博客网 时间:2024/05/02 16:08

RSA算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但那时想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作。

原理图:


C# 代码实现:

using System;using System.Collections.Generic;using System.Text;using System.Security.Cryptography;using Microsoft.Win32;using System.IO;namespace SRA{    class Program    {        static void Main(string[] args)        {            string publicKeyFile = "publicKey.txt";            string privateKeyFile = "privateKey.txt";            string publicKey = string.Empty;            string privateKey = string.Empty;            Console.WriteLine("①创建公私钥对:");            RSA.GenneralRSAKey(privateKeyFile, publicKeyFile);            publicKey = RSA.ReadPublicKey(publicKeyFile);            privateKey = RSA.ReadPrivateKey(privateKeyFile);            Console.WriteLine("公钥:" + publicKey);            Console.WriteLine("私钥:" + privateKey);            string orgStr = "HelloWord";            Console.WriteLine("②使用公钥加密字符串:");            string secStr = RSA.RSAEncrypt(publicKey, orgStr);            Console.WriteLine(secStr);            Console.WriteLine("③使用私钥解密字符串:");            Console.WriteLine(SRA.RSA.RSADecrypt(privateKey, secStr));            Console.Read();        }    }    public class RSA    {        #region  ①生成公私钥对        /// <summary>        /// ①生成公私钥对        /// </summary>        /// <param name="PrivateKeyPath">私钥文件路径</param>        /// <param name="PublicKeyPath">公钥文件路径</param>        public static void GenneralRSAKey(string PrivateKeyPath, string PublicKeyPath)        {            try            {                RSACryptoServiceProvider provider = new RSACryptoServiceProvider();                CreatePrivateKeyXML(PrivateKeyPath, provider.ToXmlString(true));                CreatePublicKeyXML(PublicKeyPath, provider.ToXmlString(false));            }            catch (Exception exception)            {                throw exception;            }        }        #region 创建密钥文件        /// <summary>        /// 创建公钥文件        /// </summary>        /// <param name="path"></param>        /// <param name="publickey"></param>        public static void CreatePublicKeyXML(string path, string publickey)        {            try            {                if (File.Exists(path))                {                    File.Delete(path);                }                FileStream publickeyxml = new FileStream(path, FileMode.Create);                StreamWriter sw = new StreamWriter(publickeyxml);                sw.WriteLine(publickey);                sw.Close();                publickeyxml.Close();            }            catch            {                throw;            }        }        /// <summary>        /// 创建私钥文件        /// </summary>        /// <param name="path"></param>        /// <param name="privatekey"></param>        public static void CreatePrivateKeyXML(string path, string privatekey)        {            try            {                if (File.Exists(path))                {                    File.Delete(path);                }                FileStream privatekeyxml = new FileStream(path, FileMode.Create);                StreamWriter sw = new StreamWriter(privatekeyxml);                sw.WriteLine(privatekey);                sw.Close();                privatekeyxml.Close();            }            catch            {                throw;            }        }        #endregion        #endregion        #region ②读取密钥        /// <summary>        /// 读取公钥        /// </summary>        /// <param name="path"></param>        /// <returns></returns>        public static string ReadPublicKey(string path)        {            StreamReader reader = new StreamReader(path);            string publickey = reader.ReadToEnd();            reader.Close();            return publickey;        }        /// <summary>        /// 读取私钥        /// </summary>        /// <param name="path"></param>        /// <returns></returns>        public static string ReadPrivateKey(string path)        {            StreamReader reader = new StreamReader(path);            string privatekey = reader.ReadToEnd();            reader.Close();            return privatekey;        }        #endregion        #region ③加密解密        /// <summary>        /// RSA加密        /// </summary>        /// <param name="xmlPublicKey">公钥</param>        /// <param name="m_strEncryptString">MD5加密后的数据</param>        /// <returns>RSA公钥加密后的数据</returns>        public static string RSAEncrypt(string xmlPublicKey, string m_strEncryptString)        {            string str2;            try            {                RSACryptoServiceProvider provider = new RSACryptoServiceProvider();                provider.FromXmlString(xmlPublicKey);                byte[] bytes = new UnicodeEncoding().GetBytes(m_strEncryptString);                str2 = Convert.ToBase64String(provider.Encrypt(bytes, false));            }            catch (Exception exception)            {                throw exception;            }            return str2;        }        /// <summary>        /// RSA解密        /// </summary>        /// <param name="xmlPrivateKey">私钥</param>        /// <param name="m_strDecryptString">待解密的数据</param>        /// <returns>解密后的结果</returns>        public static string RSADecrypt(string xmlPrivateKey, string m_strDecryptString)        {            string str2;            try            {                RSACryptoServiceProvider provider = new RSACryptoServiceProvider();                provider.FromXmlString(xmlPrivateKey);                byte[] rgb = Convert.FromBase64String(m_strDecryptString);                byte[] buffer2 = provider.Decrypt(rgb, false);                str2 = new UnicodeEncoding().GetString(buffer2);            }            catch (Exception exception)            {                throw exception;            }            return str2;        }        #endregion      }}


算法介绍:

        算法的名字以发明者的名字命名:Ron Rivest, AdiShamir 和Leonard Adleman。早在1973年,英国国家通信总局的数学家Clifford Cocks就发现了类似的算法。但是他的发现被列为绝密,直到1998年才公诸于世。

  RSA算法是一种非对称密码算法,所谓非对称,就是指该算法需要一对密钥,使用其中一个加密,则需要用另一个才能解密。

  RSA的算法涉及三个参数,n、e1、e2。

  其中,n是两个大质数p、q的积,n的二进制表示时所占用的位数,就是所谓的密钥长度。

  e1和e2是一对相关的值,e1可以任意取,但要求e1与(p-1)*(q-1)互质;再选择e2,要求(e2*e1)mod((p-1)*(q-1))=1。

  (n及e1),(n及e2)就是密钥对。

  RSA加解密的算法完全相同,设A为明文,B为密文,则:A=B^e1 mod n;B=A^e2 mod n;

  e1和e2可以互换使用,即:A=B^e2 mod n;B=A^e1 mod n;




原创粉丝点击