阅读 145

密码学之RSA

密码学概述

密码学是研究编制密码和破译密码的技术科学。研究密码变化的客观规律,应用于编制密码以保守通信秘密的,称为编码学;应用于破译密码以获取通信情报的,称为破译学,总称密码学。

密码学的历史大致可以追溯到两千年前,相传古罗马名将凯撒大帝为了防止敌方截获情报,用密码传送情报。凯撒的做法很简单,就是对二十几个罗马字母建立一张对应表。这样,如果不知道密码本,即使截获一段信息也看不懂。

image11.png

从凯撒大帝时代到上世纪70年代这段很长的时间里,密码学的发展非常的缓慢,因为设计者基本上靠经验。没有运用数学原理。

在1976年以前,所有的加密方法都是同一种模式:加密、解密使用同一种算法。在交互数据的时候,彼此通信的双方就必须将规则告诉对方,否则没法解密。那么加密和解密的规则(简称密钥),它保护就显得尤其重要。传递密钥就成为了最大的隐患。这种加密方式被成为对称加密算法(symmetric encryption algorithm)

1976年,两位美国计算机学家 迪菲(W.Diffie)、赫尔曼( M.Hellman ) 提出了一种崭新构思,可以在不直接传递密钥的情况下,完成密钥交换。这被称为“迪菲赫尔曼密钥交换”算法。开创了密码学研究的新方向

1977年三位麻省理工学院的数学家 罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起设计了一种算法,可以实现非对称加密。这个算法用他们三个人的名字命名,叫做RSA算法。

RSA的数学原理

离散对数问题

如果让你设计一个加密容易,破解很难的算法,会想到什么呢? 方案:3xmod17=123^x \mod 17 = 12,问x是多少? x可能的值为x=16k + 13,k为正整数,这样的x有多个,根本没法确定是哪个

迪菲赫尔曼密钥交换

image.png

欧拉函数

对正整数n,在小于n的正整数之中,与n构成互质关系的数有多少个? 对这个问题的首位研究者叫作欧拉,是一个神一样的厉害人物,所以把对这个问题的解答称作欧拉函数,用φ(n)来表示

如φ(8)表示计算8的欧拉函数,和8互质的数有,1,3,5,7所以φ(8) = 4; 如φ(7)表示计算7的欧拉函数,有1,2,3,4,5,6所以φ(7) = 6;

欧拉对这个问题进行研究之后,得到了欧拉函数的两个性质:

  1. 若n为质数,则φ(n) = n - 1
  2. 若A,B互质,则φ(A * B) = φ(A) * φ(B)

结合以上两条性质可得,若A,B都是质数,则φ(A * B) = φ(A) * φ(B) = (A - 1) * (B - 1)

欧拉定理

如果两个正整数m和n互质,那么m的φ(n)次方减去1,可以被n整除

mφ(n)modn1m^{φ(n)}\mod n \equiv 1

针对上面的欧拉定理,费马又来了个小定理如果两个正整数m和n互质,而且n为质数,那么m的n-1次方减去1,可以被n整除

m(n1)modn1m^{(n - 1)} \mod n \equiv 1

模反元素

如果两个正整数e和x互质,那么一定可以找到整数d,使e * d - 1被x整除,那么d就是e相对于x的模反元素

edmodx1e \ast d \mod x \equiv 1

把欧拉定理和模反元素结合起来推导

因为1 ^ k = 1,所以mφ(n)modn1m^{φ(n)} \mod n \equiv 1 两边同时k次方后得到mkφ(n)modn1m^{kφ(n)} \mod n \equiv 1

因为1 * m = m,所以上式两边同时乘上m后得到mkφ(n)+1modnmm^{kφ(n) + 1} \mod n \equiv m

将模反元素edmodx1e \ast d \mod x \equiv 1变形后得到edkx+1e \ast d \equiv k * x + 1

再结合上述两个式子就可以得到

medmodnmm^{e * d} \mod n \equiv m

其中m,n互质,e与φ(n)互质,满足条件的d一定可以找到,我们可以举几个例子验证一下

令m = 3,n = 17,e = 5,m,n互质,e和φ(17)互质,根据模反元素求的可能的d = 16k+15\frac{16k + 1}{5},k取4的时候,d为13,代入上式中验证3513mod173 ^ {5 * 13} \mod 17结果确定等于3

多试几个m,n之后会发现,只要m < n,上面的等式就一直成立,不再需要互质了...至于为什么,俺也搞不明白,知道就好了,如果有大神知道的,还请不吝赐教

medmodnmm^{e * d} \mod n \equiv m

此时,m<n,e与φ(n)互质,d = kφ(n)+1e\frac{k * φ(n) + 1}{e}

RSA算法说明

其实得到medmodnmm^{e * d} \mod n \equiv m之后,离我们实际使用RSA算法非常接近了,实际使用中memodnCm^e \mod n \equiv C,这个过程叫作加密,再求CdmodnC^d \mod n会发现结果还是m,这个过程叫作解密,其中公钥就是n和e,私钥就是n和d,m代表明文,c代表密文

说明:

  1. n会非常大,长度一般为1024个二进制位。(目前人类已经分解的最大整数,232个十进制位,768个二进制位)
  2. 由于需要求出φ(n),所以根据欧函数特点,最简单的方式n 由两个质数相乘得到: 质数:p1、p2 Φ(n) = (p1 -1) * (p2 - 1)
  3. 最终由φ(n)得到e 和 d

总共生成6个数字:p1、p2、n、φ(n)、e、d,除了公钥用到了n和e其余的4个数字是不公开的,目前皮杰RSA得到d的方式如下:

  1. 要想求出私钥d,由于e * d = k * φ(n) + 1,要知道e和φ(n);
  2. e是公开的,但是要得到φ(n),必须知道p1和p2;
  3. 由于n = p1 * p2,只有将n因数分解才能算出;

RSA的终端演练

Mac电脑的终端可以直接使用OpenSSL进行RSA的命令运行。由于Mac系统内置OpenSSL(开源加密库),所以我们可以直接在终端上使用命令来玩RSA. OpenSSL中RSA算法常用指令主要有三个: image.png

  1. 生成RSA私钥,密钥长度为1024bit:openssl genrsa -out private.pem 1024Snip20210609_1.png

  2. 从私钥中提取公钥:openssl rsa -in private.pem -pubout -out public.pemSnip20210609_2.png可以查看一下公钥和私钥的内容image.png

  3. 还可以使用命令openssl rsa -in private.pem -text -out private.txt将私钥转成文本,并查看里面的内容Snip20210609_6.png

  4. 接下来我们使用公钥对一段文本进行加密:openssl rsautl -encrypt -in message.txt -inkey public.pem -pubin -out enc.txtSnip20210609_7.png可以看到message.txt的内容由密码123456已经变成了一堆乱码,(没使用过vim编辑器的同学也可以直接创建一个txt文件)

  5. 使用私钥进行解密:openssl rsautl -decrypt -in enc.txt -inkey private.pem -out dec.txtSnip20210609_8.png

在macOS中我们是不能直接使用pem文件的,需要使用的der格式和p12格式的文件

  1. 首先需要一个证书请求文件,这个做过iOS开发的同学应该都很熟悉了openssl req -new -key private.pem -out rsacert.csrSnip20210609_9.png

  2. 一般我们配置证书的时候,是使用上面生成的证书请求文件去苹果服务器签名后得到证书,但是现在我们只是演示,就自己签名了:openssl x509 -req -days 3650 -in rsacert.csr -signkey private.pem -out rsacert.crtSnip20210609_10.png

  3. 通过crt文件生成p12文件:openssl pkcs12 -export -out p.p12 -inkey private.pem -in rsacert.crt设置密码并再次确认之后得到p12文件Snip20210609_11.png

其实在平时日常开发中,证书这些东西,我们iOS开发者直接使用就行了,基本是不会需要我们iOS开发来生成配置

RSA的代码代码演练

在iOS系统中,crt文件也不能直接使用,需要转成der文件,命令如下:
openssl x509 -outform der -in rsacert.crt -out rsacert.derSnip20210609_12.png

  1. 加载公钥和私钥Snip20210609_14.png其中RSACryptor是已经封装好的RSA工具类,有需要的可以自己去下载

  2. 加密hello world并输出加密结果Snip20210609_15.png

  3. 解密过程Snip20210609_16.png

文章分类
iOS
文章标签