【密码学】RSA加解密原理及其Java实现算法
来源:互联网 发布:wind终端mac版 编辑:程序博客网 时间:2024/05/21 06:45
密钥生成
RSA的密钥通过如下步骤生成:
选取两个不同的质数p和q
- 为了安全考虑,p和q应该随机选取,并且具有相似的数量级。如果p和q仅仅通过几个数字使得长度不同,那么分解因子更加困难
计算n = pq
- n作为公钥和私钥的模数。n的比特数就是密钥的长度
计算n的欧拉函数φ(n) = (p-1)(q-1)
选取一个整数e,1 < e < φ(n),e与φ(n)互质
计算e模φ(n)的逆d
- d就是使得ed ≡ 1(mod φ(n))
- e一般是一个短比特长度、小海明权重的数,这样使得加密更加有效。e一般选取2^16 + 1 = 65537。如果e比较小(比如3),那么在某些情况显得很不安全。
- e作为公钥发布
- d作为私钥保存
加解密过程
加密
如果Bob想要发送消息M给Alice
他首先把M转换为整数m(0 < m < n),然后用Alice的公钥e计算密文c,表达式为:
如果使用平方-乘算法可以使计算非常快,即使是500-bit的整数
然后Bob把c发送给Alice
解密
Alice用私钥d把密文c恢复为整数m
然后Alice把整数m恢复为明文M
例子
选择p和q
p = 61q = 53
计算n = pq
n = 61 * 53 = 3233
计算φ(n)
φ(3233) = 3120
选择e
e = 17
计算d
d = 2753
加密
65^17 ≡ 2790 (mod 3233)
解密
2790^2753 ≡ 65 (mod 3233)
算法
源代码
下面算法是使用Java的BigInteger类,主要是为了阐释RSA的加解密过程,算法不具有代表性,仅供参考
import java.math.BigInteger;import java.util.Random;public class RSAs { private static BigInteger n; // large prime private static BigInteger e; // public key private static BigInteger b; // private key private static BigInteger p; // prime private static BigInteger q; // prime public static void main(String[] args) { String plaintext = "The quick brown fox jumps over the lazy dog"; RSAs rsas = new RSAs(); rsas.giveKey(); BigInteger[] encrypt = rsas.encrypt(plaintext); String decrypt = rsas.decrypt(encrypt); System.out.println("\nplaintext:" + plaintext + "\n\nencrpyt:"); for (int i = 0; i < encrypt.length; ++i) { System.out.println(encrypt[i]); } System.out.println("\ndecrypt:" + decrypt); } // RSA encryption public BigInteger[] encrypt(String plaintext) { BigInteger[] encrypt = new BigInteger[plaintext.length()]; BigInteger m, c; for (int i = 0; i < plaintext.length(); ++i) { m = BigInteger.valueOf(plaintext.charAt(i)); c = m.modPow(e, n); encrypt[i] = c; } return encrypt; } // RSA decryption public String decrypt(BigInteger[] encrypt) { StringBuffer plaintext = new StringBuffer(); BigInteger m, c; for (int i = 0; i < encrypt.length; ++i) { c = encrypt[i]; m = c.modPow(b, n); plaintext.append((char) m.intValue()); } return plaintext.toString(); } // give public key and private key public void giveKey() { // get p,q,n,e,b producePQ(); n = p.multiply(q); BigInteger eulerN = p.subtract(new BigInteger("1")).multiply(q.subtract(new BigInteger("1"))); produceEB(eulerN); System.out.println("n:" + n + "\np:" + p + "\nq:" + q + "\ne:" + e + "\nb:" + b); } // large prime p and q generation public void producePQ() { p = BigInteger.probablePrime(32, new Random()); q = BigInteger.probablePrime(32, new Random()); while (p.equals(q)) { p = BigInteger.probablePrime(32, new Random()); q = BigInteger.probablePrime(32, new Random()); } } // produce public key e,private key b public void produceEB(BigInteger eulerN) { e = BigInteger.probablePrime((int) (Math.random() * 63 + 2), new Random()); while (e.compareTo(eulerN) != -1 | eulerN.divide(e).equals(0)) { e = BigInteger.probablePrime((int) (Math.random() * 63 + 2), new Random()); } //e = BigInteger.valueOf(65537); b = e.modInverse(eulerN); }}
运行结果
n:7722718897492023517p:2362511213q:3268860209e:11182711b:7692894186493341255plaintext:The quick brown fox jumps over the lazy dogencrpyt:460677377892844302231910653542017758692063576957539994540324066101898781055046430765699281330616724493591560186042592828770772456814118024883408945721037207707714312482840324066101898781055072847910235050690201666173794082244580743509746308901414877173124234753816002862511757604585560324066101898781055026005102734154614957435097463089014148570658665461456630932406610189878105505828898437482186613672449359156018604210000311860047525311594082521594404755641933813051444079632406610189878105507435097463089014148235250470560124312220635769575399945401666173794082244580324066101898781055033821947450664659593191065354201775869206357695753999454032406610189878105506165260746857331774868384751760782699745245957974217151927654902873831066043240661018987810550426189291042634827074350974630890141483115531137912443469decrypt:The quick brown fox jumps over the lazy dog
1 0
- 【密码学】RSA加解密原理及其Java实现算法
- 【密码学】AES加解密原理及其C++实现算法
- 【密码学】维吉尼亚密码加解密原理及其破解算法Java实现
- 【密码学】RC4加解密原理及其Java和C实现算法
- 密码学(二)—RSA后端加解密java实现
- RSA加解密算法原理
- [密码学--RSA的加解密]
- RSA算法加解密(JAVA)
- Java,RSA加解密算法
- RSA算法加解密(JAVA)
- java实现的简单RSA加解密算法
- [JAVA加解密]RSA算法、ElGamal算法
- RSA加解密原理
- RSA加/解密算法--python实现
- Java,Android使用RSA 算法加解密
- RSA加解密算法
- RSA 加解密算法
- RSA 加解密算法
- tomcat + 花生壳
- 编程的感悟
- Pajek的.mat文件的数据的输入格式
- 一个屌丝程序猿的人生(六十二)
- [LeetCode]223. Rectangle Area
- 【密码学】RSA加解密原理及其Java实现算法
- Python 基于Hash算法对海量文件去重方案
- 一个简单的输入关键字添加标签效果
- 微信小程序实现给循环列表添加点击样式
- 启动或停止Samba服务
- 217. Contains Duplicate
- Keil(MDK-ARM)介绍、下载、安装与注册
- Python与C++区别
- 在ArcGIS WebAppBuilder中的widget中嵌入EasyUI的图形化控件