玩转RSA
经过上一篇原理篇的讲解,相信大多数朋友还记得这个公式:
至于这个公式怎么来的,可以参看 RSA原理篇
下面我们一起来验证一下这个公式。
由于 且m < n。
我们取 m = 5, n = 17,φ17 = 16,即x = φn = 16;
由于 e 与 x 互为质数,且 e*d mod x 1,即 e * d mod 16 1。假设e = 11。d = 3,当然也可以有很多个值。
至此我们所要求的数据已经具备:
公钥:n 和 e, 其中 n = 17, e = 11;
私钥:n 和 d,其中 n = 17, d = 3;
用 python3 分别对明文 m=5 、8、13进行加密和解密,过程如下:
在这个过程中,主要是为了拿到公钥和私钥。同时还有一个限制条件 m < n,所以为了保证公钥和私钥一直有效,就要保证 n 足够大。
那么怎样来保证n足够大呢?
1、通常n 为一1024个二进制位,目前人类已经分解出的最大的整数是232个十进制位,即768个二进制位,所以用1024位目前是安全的,当然也可以根据需要使用2048位。
2、同时我们要求出φn的值,根据欧拉函数特点,最简单的方式是n由两个质数相乘得到。即 n = p1*p2;φn = φp1 * φp2 = (p1 - 1)*(p2 -1)。
3、最终由φn得到e和d。
目前整个过程一共由6个数字:p1,p2,n,φn,e,d。
RSA的安全性
在上面提到的6个数字中,其中n 和e是公钥,需要对外公开,其余的4位都是不公开的。所以要想破解RSA,首先就要拿到私钥d 和 n,由于n在公钥中已经得到,剩下的问题就是如何获取d了。
目前破解RSA得到d的方式如下:
1、由于 e * d = k * φn + 1;所以要知道e 和 φn;
2、e是公开的,只需要知道φn就可以,要想得到φn,就必须知道p1 和 p2。
3、由于n = p1 * p2,就只能通过因式分解来得到。
基于以上的步骤分析,只能是暴力破解了,刚才我们提到目前已经能分解的最大数字是768个二进制位,而我们同常所用的n的长度是1024个二进制位。所以目前来说RSA是安全的。
当然在量子计算机普及以后,1024位的长度被破解当然不在话下了。RSA的安全性也就不存在了。但是这样会导致什么问题呢?目前银行系统包括这两年兴起的比特币都要被改写。未来还是充满了无限可能哦~
终端玩转
Mac OS 终端自带了OpenSSL库,我们可以直接通过终端玩转rsa.
常用的有三个命令,分别是 genrsa、rsautl 和 rsa。
1、生成rsa私钥
格式:openssl genrsa -out 私钥文件名 私钥长度(512/2014/2048)
举例: openssl genrsa -out private.pem 1024
2、通过私钥导出公钥
格式:openssl rsa -in 私钥文件名 -pubout -out 公钥文件名
举例:openssl rsa -in private.pem -pubout -out public.pem
3、使用公钥加密文件:
格式:openssl rsautl -encrypt -in -加密问价名 -inkey 公钥 -pubin -out 加密后的文件名
举例:openssl rsautl -encrypt -in message.txt -inkey public.pem -pubin -out enc.txt
4、使用私钥解密文件:
格式:openssl rsautl -decrypt -in 加密文件名 -inkey 私钥文件 -out 解密后的文件
举例:openssl rsautl -decrypt -in enc.txt -inkey private.pem -out dec.txt
5、使用私钥加签
格式:openssl rsautil -sign -in 需要加密的文件 -inkey 私钥 -out -输出文件
举例:openssl rsautl -sign -in message.txt -inkey private.pem -out encsign.bin
6、使用公钥验签
格式:openssl rsautl -verify -in 需要验签的文件名 -inkey 公钥 -pubin -out 解密后的文件
举例:openssl rsautl -verify -in encsign.bin -inkey public.pem -pubin -out decsign.txt
RSA特点及用途:
1、效率低,适用于小数据加密,比如用于对称加密的key进行加密;
2、数字签名:对哈希值进行加密。
以上基本就是RSA基本用法和特点分析,如有不足的地方,请各位朋友一起探讨学习。