RSA加密原理与过程
一、基本的数学概念与理论
- 最大公因数,又叫最大公约数,是指两个或多个整数共有约数中最大的一个,使用符号gcd来表示,例如gcd(a,b)表示a和b的最大公约数。
- 欧几里得算法又称辗转相除法,用于计算两个整数的最大公约数,公式表示为gcd(a,b)=gcd(b,a mod b)。
- 欧几里得扩展算法,对于不完全为 0 的非负整数 a,b,必然存在存在整数对 x,y ,使得 gcd(a,b)=ax+by。
- 最小公倍数,两个或多个整数公有的倍数叫做它们的公倍数,其中除0以为最小的一个公倍数就叫做这几个整数最小公倍数,使用符号lcm来表示,例如lcm(a,b)表示,a和b的最小公倍数。
- 质数,又称为素数,是指只能被1或自身整除的正整数。如果整数a和b的最大公约数为1,也就是gcd(a,b)=1,则称a和b互质。
- 同余,使用符号≡表示,假设m是大于1的正整数,a和b是整数,如果m|(a-b),则称a与b关于模m同余,记做a≡b(mod m),读作a同余于b模m。
- 模反元素,如果两个正整数a和n互质,那么一定能知道整数b,使得ab≡1(mod n),那么我们称b为a关于模n的模反元素。
- 欧拉函数,在数论中,对正整数n,小于n的正整数中与n互质的数目称为欧拉函数,使用符号φ(n)来表示。
- 费马小引理,假设a为不能被质数p整除的正整数,则必有a^(p-1)=1(mod p)。
- 欧拉定理又叫费马欧拉定理,假设a和n都是正整数,并且gcd(a,n)=1,则存在a^φ(n)≡1(mod n)。
- 中国余数理论(CRT),假设p和q是两个不同的质数,n=pq,对于任意两个数x1,x2,其中0 ≤ x1 < p, 0 ≤ x2 < q,必然存在唯一的数x,使得 x1 = x mod p 并且 x2 = x mod q。
- 算数基本定理又叫正整数唯一分解定理,对于任意自然数n(n>=2),均可分解为质数的乘积,如果不考虑排列顺序,该分解是唯一的。
二、RSA加密算法概要
非对称加密又叫公开秘钥加密,需要两个秘钥:公开秘钥(publickKey)和私有秘钥(privateKey)。公钥与私钥是一对儿,私钥由公钥决定,一般使用公钥加密,私钥解密,当然使用私钥加密,使用公钥解密也可以,但因为公钥是公开的,失去了加密的的意义。
RSA加密算法,是非对称加密的一种实现,是基于一个简单的数论事实,即将两个大的质数相乘非常容易,但是想要对其乘积进行因式分解为两个大的质数缺非常困难,因此可以将乘积公开作为加密秘钥,使用公式表示为(m^e)^d≡m(mod n),m表示消息,(n,e)表示公钥,(n,d)表示私钥,根据初等数论,即使知道e,n也很难推导出d。
三、RSA秘钥生成步骤
- 选取两个大的质数p和q,出于安全考虑p和q都要随机产生,并且足够大位数也要有差别。
- 计算n=pq,n被用做公钥和私钥的模数。一般以n的二进制表示的位数作为秘钥的长度。
- 计算欧拉函数φ(n)=(p-1)(q-1)。
- 选取一个整数e,使得e大于1小于 φ(n)并且gcd(e,φ(n))=1,也就是说e要与φ(n)互质。
- 计算d使得d*e≡ 1 (mod φ(n))。
- 使用(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)
六、例子
- 选取p=61,q=53
- 计算n=61*53=3233
- 计算欧拉函数φ(n)=(61-1)(53-1)=3120
- 选取一个数e,取自范围为(1,3120),并且要与3120互质,这里选取e=17
- 计算d,d*17≡1(mod 3120),根据欧几里得扩展算法,得到d等于2753
- 公钥加密c=m^17(mod 3233),假设m取65,c=65^17(mod 3233)=2790
- 私钥解密c^d≡2790^2753≡m^17^2790≡m(mod 3233)。
七、使用中国余数定理加快解密过程
- d mod (p-1) =2753 mod (61-1)=53,使用符号dp表示
- d mod(q-1)=2753 mod (53-1)=49,使用符号dq表示
- 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加密原理与过程相关推荐
- rsa加密原理数学证明_非对称加密算法——RSA加密原理及数学推导
说明:原创不易,著作权仅归作者本人所有,转载请注明出处. 建议:建议阅读时间15min+.证明过程可能看着枯燥,需要动手. 一. RSA是什么? 看到标题的第一瞬间,先想一下,RSA是什么呢?百度百 ...
- 密码学之RSA加密原理解析
密码学是指研究信息加密,破解密码的技术科学.密码学的起源可追溯到2000年前.而当今的密码学是以数学为基础的. 密码学的历史大致可以追溯到两千年前,相传古罗马名将凯撒大帝为了防止敌方截获情报, ...
- RSA 加密原理和一些知识笔记
RSA 加密原理和一些知识笔记 原文地址: 01:RSA 加密和原理 .pem .csr .crt .der .p12文件的区别 base64 (https://www.cnblogs.com/zyz ...
- 非对称加密算法--RSA加密原理及运用
密码学是在编码与破译的斗争实践中逐步发展起来的,并随着先进科学技术的应用,已成为一门综合性的尖端技术科学. 密码学发展史 在说RSA加密算法之前, 先说下密码学的发展史.其实密码学的诞生,就是为了运用 ...
- 用c语言elgamal共密钥密码加密算法,非对称密钥体制RSA加密原理
一.非对称密钥加密概述 前面讲述了对称密钥加密体制.使用对称密钥加密体制进行保密通信时,任意不同的两个用户之间都应该使用互不相同的密钥.这样,如果一个网络中有n个用户,他们之间彼此都可能进行秘密通信, ...
- RSA加密原理与RSA公钥加密系统、数字签名
通过公钥加密系统,可以对传输于两个通信单位之间的消息进行加密,即使窃听者窃听到加密之后的消息,也不能对其破译. 1.RSA公钥加密原理 1.1 几个核心概念 公钥P与公钥函数P() 密钥S与密钥函数S ...
- RSA加密原理:非对称加密鼻祖
加密算法 加密算法,RSA是绕不开的话题,因为RSA算法是目前最流行的公开密钥算法,既能用于加密,也能用户数字签名.不仅在加密货币领域使用,在传统互联网领域的应用也很广泛.从被提出到现在20多年,经历 ...
- RSA加密原理详解,以及RSA中的数论基础
文章目录 1. RSA加密算法介绍 2. RSA密钥生成 3. RSA加密和解密 4. RSA的安全性 5.涉及到的数论基础 5.1. 模的逆元 5.1.1. 扩展欧几里得算法计算模逆元 5.1.2. ...
- 一个简单地C语言程序展示RSA加密原理
#include<stdio.h> #include<stdlib.h> #include<time.h> #include<math.h>//质数判定 ...
最新文章
- Codeforces 846 B Math Show DFS + 贪心
- 816固件a2可以升a1吗_关于A1,A2,A3,B1,B2驾驶证使用新规定,你知多少?
- Java的包裹wrap
- 浮点数运算的精度问题:以js语言为例
- 宝塔 php curl 配置,【笔记】宝塔面板配置laravel
- LeetCode算法总结-回溯法与深度优先搜索
- scorm课件学习状态
- 函数作为参数传递至函数内部进行调用
- winform中listview选中整行_Excel办公实操,操作区域的3大小技巧,办公中的你使用过吗...
- mqtt+uniapp 发布/订阅实例
- Silverligth API for ArcGIS应用程序IIS发布
- VSCode配置cpp环境
- (java毕业设计)基于java学生宿舍管理系统
- Python编写时钟表turtle
- 欧拉计划(1~3)ps:以后看题一定要认真
- 怎么更改网络选项为家庭计算机,我的现在是公用网络我想更改为家庭网络应该如何更改...
- spring Clound EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT. RENEW
- STM32F3 GPIO的八种模式及工作原理
- 计算机什么课学mcmc,MCMC案例学习
- linux脚本一致性判断,生产环境之文件一致性检测脚本