一、基本的数学概念与理论

  1. 最大公因数,又叫最大公约数,是指两个或多个整数共有约数中最大的一个,使用符号gcd来表示,例如gcd(a,b)表示a和b的最大公约数。
  2. 欧几里得算法又称辗转相除法,用于计算两个整数的最大公约数,公式表示为gcd(a,b)=gcd(b,a mod b)。
  3. 欧几里得扩展算法,对于不完全为 0 的非负整数 a,b,必然存在存在整数对 x,y ,使得 gcd(a,b)=ax+by。
  4. 最小公倍数,两个或多个整数公有的倍数叫做它们的公倍数,其中除0以为最小的一个公倍数就叫做这几个整数最小公倍数,使用符号lcm来表示,例如lcm(a,b)表示,a和b的最小公倍数。
  5. 质数,又称为素数,是指只能被1或自身整除的正整数。如果整数a和b的最大公约数为1,也就是gcd(a,b)=1,则称a和b互质。
  6. 同余,使用符号≡表示,假设m是大于1的正整数,a和b是整数,如果m|(a-b),则称a与b关于模m同余,记做a≡b(mod m),读作a同余于b模m。
  7. 模反元素,如果两个正整数a和n互质,那么一定能知道整数b,使得ab≡1(mod n),那么我们称b为a关于模n的模反元素。
  8. 欧拉函数,在数论中,对正整数n,小于n的正整数中与n互质的数目称为欧拉函数,使用符号φ(n)来表示。
  9. 费马小引理,假设a为不能被质数p整除的正整数,则必有a^(p-1)=1(mod p)。
  10. 欧拉定理又叫费马欧拉定理,假设a和n都是正整数,并且gcd(a,n)=1,则存在a^φ(n)≡1(mod n)。
  11. 中国余数理论(CRT),假设p和q是两个不同的质数,n=pq,对于任意两个数x1,x2,其中0 ≤ x1 < p, 0 ≤ x2 < q,必然存在唯一的数x,使得 x1 = x mod p 并且 x2 = x mod q。
  12. 算数基本定理又叫正整数唯一分解定理,对于任意自然数n(n>=2),均可分解为质数的乘积,如果不考虑排列顺序,该分解是唯一的。

二、RSA加密算法概要

非对称加密又叫公开秘钥加密,需要两个秘钥:公开秘钥(publickKey)和私有秘钥(privateKey)。公钥与私钥是一对儿,私钥由公钥决定,一般使用公钥加密,私钥解密,当然使用私钥加密,使用公钥解密也可以,但因为公钥是公开的,失去了加密的的意义。
RSA加密算法,是非对称加密的一种实现,是基于一个简单的数论事实,即将两个大的质数相乘非常容易,但是想要对其乘积进行因式分解为两个大的质数缺非常困难,因此可以将乘积公开作为加密秘钥,使用公式表示为(m^e)^d≡m(mod n),m表示消息,(n,e)表示公钥,(n,d)表示私钥,根据初等数论,即使知道e,n也很难推导出d。

三、RSA秘钥生成步骤

  1. 选取两个大的质数p和q,出于安全考虑p和q都要随机产生,并且足够大位数也要有差别。
  2. 计算n=pq,n被用做公钥和私钥的模数。一般以n的二进制表示的位数作为秘钥的长度。
  3. 计算欧拉函数φ(n)=(p-1)(q-1)。
  4. 选取一个整数e,使得e大于1小于 φ(n)并且gcd(e,φ(n))=1,也就是说e要与φ(n)互质。
  5. 计算d使得d*e≡ 1 (mod φ(n))。
  6. 使用(n,e)作为公钥,(n,d)作为私钥。

四、加密

假设M代表要加密的密文,需要将M转换为一个大数m,使用公钥(n,e)加密,加密后的密文用c来表示,公式表示如下:c≡m^e(mod n)

五、解密

使用私钥(n,d)来解密,公式表示如下:c^d≡(m^e)^d≡m(mod n)

六、例子

  1. 选取p=61,q=53
  2. 计算n=61*53=3233
  3. 计算欧拉函数φ(n)=(61-1)(53-1)=3120
  4. 选取一个数e,取自范围为(1,3120),并且要与3120互质,这里选取e=17
  5. 计算d,d*17≡1(mod 3120),根据欧几里得扩展算法,得到d等于2753
  6. 公钥加密c=m^17(mod 3233),假设m取65,c=65^17(mod 3233)=2790
  7. 私钥解密c^d≡2790^2753≡m^17^2790≡m(mod 3233)。

七、使用中国余数定理加快解密过程

  1. d mod (p-1) =2753 mod (61-1)=53,使用符号dp表示
  2. d mod(q-1)=2753 mod (53-1)=49,使用符号dq表示
  3. q^-1 mod p = 53 ^ -1 mod 61 = 38,使用符号qinv来表示,其实就是q的关于模p的模反元素。通过模反元素可以得到(qinv * q) mod p = 38 * 53 mod 61 = 1。下面是使用这些常数来计算m的过程:
m1 = c^dp mod p = 2790^53 mod 61 = 4;
m2 = c^dq mod q = 2790^49 mod 53 = 12;
h = (qinv * (m1 - m2)) mod p = (38 * -8) mod 61 = 1;
m = m2 + h * q = 17 + 1 * 53 = 65

上面的加解密可以使用欧拉定理和费马费马小引理来证明,这里不给出证明过程。
我们在RSA算法过程称中使用到的有如下量:

变量 说明
d the private exponent
dp d mod (p-1)
dq d mod (q-1)
e the public exponent
qinv q^-1 mod p
n modulus
p prime 1
q prime 2

以下是以C#生成的私钥钥,Modulus节点是n,Exponent节点代表e,由n和e构成公钥,
InverseQ表示qinv,其他都与小写的对应,节点内部都是对大数的字符串表示进行base64的加密。

<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>

八、C#RSA加密代码实现

using System;
using System.Security.Cryptography;
using System.Text;
using System.Xml;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Encodings;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Pkcs;
using Org.BouncyCastle.Security;namespace RSATest
{   // 下面的key都必须是xml格式class RSAUtils{public void GetRSAKeyPair(ref string privateKey, ref string publicKey){RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider();privateKey = rsaProvider.ToXmlString(true);publicKey = rsaProvider.ToXmlString(false);}//C#默认只能使用[公钥]进行加密public string EncryptByPublicKey(string publicKey, string data){RSACryptoServiceProvider rsaPublic = new RSACryptoServiceProvider();rsaPublic.FromXmlString(publicKey);byte[] publicValue = rsaPublic.Encrypt(Encoding.UTF8.GetBytes(data), false);return Convert.ToBase64String(publicValue); }//C#默认只能使用[私钥]进行解密public string DecryptByPrivateKey(string privateKey, string data){RSACryptoServiceProvider rsaPrivate = new RSACryptoServiceProvider();rsaPrivate.FromXmlString(privateKey);byte[] privateValue = rsaPrivate.Decrypt(Convert.FromBase64String(data), false);return Encoding.UTF8.GetString(privateValue);}// 使用第三方组件进行私钥加密public string EncryptByPrivateKey(string privateKey, string data){RSACryptoServiceProvider privateRsa = new RSACryptoServiceProvider();privateRsa.FromXmlString(privateKey);AsymmetricCipherKeyPair keyPair = DotNetUtilities.GetKeyPair(privateRsa);IBufferedCipher cipher = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding");cipher.Init(true, keyPair.Private);byte[] dataToEncrypt = Encoding.UTF8.GetBytes(data);byte[] outBytes = cipher.DoFinal(dataToEncrypt); return Convert.ToBase64String(outBytes);}// 使用第三方组件公钥解密public string DecryptByPublicKey(string publicKey, string data){RSACryptoServiceProvider rsaPublic = new RSACryptoServiceProvider();rsaPublic.FromXmlString(publicKey);RSAParameters rsaParameters = rsaPublic.ExportParameters(false);BigInteger biModulus = new BigInteger(1, rsaParameters.Modulus);BigInteger biExponent = new BigInteger(1, rsaParameters.Exponent);RsaKeyParameters publicParameters = new RsaKeyParameters(false, biModulus, biExponent);IAsymmetricBlockCipher eng = new Pkcs1Encoding(new RsaEngine());eng.Init(false, publicParameters);byte[] encryptedData = Convert.FromBase64String(data);encryptedData = eng.ProcessBlock(encryptedData, 0, encryptedData.Length);return Encoding.UTF8.GetString(encryptedData, 0, encryptedData.Length);}// C#格式秘钥转java格式public string RSAPrivateKeyDotNet2Java(string privateKey){XmlDocument doc = new XmlDocument();doc.LoadXml(privateKey);if (doc.DocumentElement == null)return null;BigInteger m = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Modulus")[0].InnerText));BigInteger exp = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Exponent")[0].InnerText));BigInteger d = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("D")[0].InnerText));BigInteger p = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("P")[0].InnerText));BigInteger q = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Q")[0].InnerText));BigInteger dp = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("DP")[0].InnerText));BigInteger dq = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("DQ")[0].InnerText));BigInteger qinv = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("InverseQ")[0].InnerText));RsaPrivateCrtKeyParameters privateKeyParam = new RsaPrivateCrtKeyParameters(m, exp, d, p, q, dp, dq, qinv);PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateKeyParam);byte[] serializedPrivateBytes = privateKeyInfo.ToAsn1Object().GetEncoded();return Convert.ToBase64String(serializedPrivateBytes);}}
}

RSA加密原理与过程相关推荐

  1. rsa加密原理数学证明_非对称加密算法——RSA加密原理及数学推导

    说明:原创不易,著作权仅归作者本人所有,转载请注明出处. 建议:建议阅读时间15min+.证明过程可能看着枯燥,需要动手. 一.  RSA是什么? 看到标题的第一瞬间,先想一下,RSA是什么呢?百度百 ...

  2. 密码学之RSA加密原理解析

      密码学是指研究信息加密,破解密码的技术科学.密码学的起源可追溯到2000年前.而当今的密码学是以数学为基础的.   密码学的历史大致可以追溯到两千年前,相传古罗马名将凯撒大帝为了防止敌方截获情报, ...

  3. RSA 加密原理和一些知识笔记

    RSA 加密原理和一些知识笔记 原文地址: 01:RSA 加密和原理 .pem .csr .crt .der .p12文件的区别 base64 (https://www.cnblogs.com/zyz ...

  4. 非对称加密算法--RSA加密原理及运用

    密码学是在编码与破译的斗争实践中逐步发展起来的,并随着先进科学技术的应用,已成为一门综合性的尖端技术科学. 密码学发展史 在说RSA加密算法之前, 先说下密码学的发展史.其实密码学的诞生,就是为了运用 ...

  5. 用c语言elgamal共密钥密码加密算法,非对称密钥体制RSA加密原理

    一.非对称密钥加密概述 前面讲述了对称密钥加密体制.使用对称密钥加密体制进行保密通信时,任意不同的两个用户之间都应该使用互不相同的密钥.这样,如果一个网络中有n个用户,他们之间彼此都可能进行秘密通信, ...

  6. RSA加密原理与RSA公钥加密系统、数字签名

    通过公钥加密系统,可以对传输于两个通信单位之间的消息进行加密,即使窃听者窃听到加密之后的消息,也不能对其破译. 1.RSA公钥加密原理 1.1 几个核心概念 公钥P与公钥函数P() 密钥S与密钥函数S ...

  7. RSA加密原理:非对称加密鼻祖

    加密算法 加密算法,RSA是绕不开的话题,因为RSA算法是目前最流行的公开密钥算法,既能用于加密,也能用户数字签名.不仅在加密货币领域使用,在传统互联网领域的应用也很广泛.从被提出到现在20多年,经历 ...

  8. RSA加密原理详解,以及RSA中的数论基础

    文章目录 1. RSA加密算法介绍 2. RSA密钥生成 3. RSA加密和解密 4. RSA的安全性 5.涉及到的数论基础 5.1. 模的逆元 5.1.1. 扩展欧几里得算法计算模逆元 5.1.2. ...

  9. 一个简单地C语言程序展示RSA加密原理

    #include<stdio.h> #include<stdlib.h> #include<time.h> #include<math.h>//质数判定 ...

最新文章

  1. Codeforces 846 B Math Show DFS + 贪心
  2. 816固件a2可以升a1吗_关于A1,A2,A3,B1,B2驾驶证使用新规定,你知多少?
  3. Java的包裹wrap
  4. 浮点数运算的精度问题:以js语言为例
  5. 宝塔 php curl 配置,【笔记】宝塔面板配置laravel
  6. LeetCode算法总结-回溯法与深度优先搜索
  7. scorm课件学习状态
  8. 函数作为参数传递至函数内部进行调用
  9. winform中listview选中整行_Excel办公实操,操作区域的3大小技巧,办公中的你使用过吗...
  10. mqtt+uniapp 发布/订阅实例
  11. Silverligth API for ArcGIS应用程序IIS发布
  12. VSCode配置cpp环境
  13. (java毕业设计)基于java学生宿舍管理系统
  14. Python编写时钟表turtle
  15. 欧拉计划(1~3)ps:以后看题一定要认真
  16. 怎么更改网络选项为家庭计算机,我的现在是公用网络我想更改为家庭网络应该如何更改...
  17. spring Clound EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT. RENEW
  18. STM32F3 GPIO的八种模式及工作原理
  19. 计算机什么课学mcmc,MCMC案例学习
  20. linux脚本一致性判断,生产环境之文件一致性检测脚本

热门文章

  1. jieba入门记录——nltk中文语料处理
  2. vue uniapp 实现走马灯 ,文字横向滚动
  3. 王自如评价鸿蒙OS,王自如上手评测坚果Pro 2:来听听大神怎么说!
  4. C++之mutable
  5. HR:你该如何调薪加薪?
  6. Android自定义幸运转盘
  7. 「BUAA OO Unit 1 HW4」第一单元总结 —— 递归下降思想处理表达式
  8. 分布式 - 分布式系统下调用链追踪技术
  9. podman基础入门
  10. 066-JAVA项目实训:仿QQ即时通讯软件系列讲座一(需求分析)