数据加密:RSA 加解密

一、加解密方法

对于RSA加解密来讲,在iOS的API中一样也是提供了这两种形式的方法。git

SecKeyEncrypt(加密)
SecKeyDecrypt(解密)
复制代码

openssl 一样也提供了一系列的方法:github

RSA_public_encrypt
RSA_private_encrypt
RSA_public_decrypt
RSA_private_decrypt
复制代码

相比较而言,openssl 提供的方法更为明确,好比:公钥解密,私钥解密,私钥加密,公钥解密。虽然 iOS 原生给出的只是加密和解密的方法,可是在方法注释中明确说了,加密用的就是公钥,解密用的就是私钥。算法

其实公钥加密私钥解密也是最经常使用的方式,私钥加密公钥解密用的并很少,可是私钥加密公钥解密有的时候也是须要的。若是真的须要私钥加密公钥解密,openssl 会更方便一点,但其实 iOS 也能够作私钥加密公钥解密。安全

这里大体说一下RSA加解密的过程:bash

1.生成密钥加密

公钥 (E,N)  
私钥 (E,D,N)
复制代码

2.加解密spa

密文 = 明文E  % N  
明文 = 密文D  % N

咱们经过一个具体的例子来直观体验下,通过计算咱们如今获得一对具体的密钥对:code

公钥=(E,N) = (5,323)  
私钥=(D,N) = (29,323)  

B = AE  mod N = pow(123, 5) % 323 = 225  
A = BD  mod N = pow(225, 29) % 323 = 123  

若是 A(123) 为明文,那上面的过程就是 公钥加密私钥解密;
若是 B(225) 为明文,那上面的过程就是 私钥加密公钥解密;ssl

换一下顺序可能会更清除一点:get

A = BD  mod N = pow(225, 29) % 323 = 123 (私钥加密)   
B = AE  mod N = pow(123, 5) % 323 = 225 (公钥解密)  

这样一来咱们就会发现,其实加解密是同一个方法。那为何会有加密和解密两个方法呢?个人理解是:

加密就是,传入数据直接作计算(就像上面的那样)
解密就是,传入数据直接作计算(仍是上面的那样),不过会根据填充模式作数据处理,把填充的随机数剔除掉。

因此从原理上来讲私钥加密公钥解密是行的通的,只是须要本身作一些数据上的处理。具体实现能够看Demo

二、分段加密

RSA算法自己要求加密内容也就是明文长度 m 必须 0<m<n ,也就是说内容这个大整数不能超过 n,不然就出错。那么若是 m=0,RSA加密器会直接返回全0结果。因此在对较长的数据进行加密的时候要把数据分段,每一段的数据长度不能大于模数长度(密钥长度)。

在实际的 RSA 加密中,分段的长度跟填充模式也有必定的关系:

填充方式 最大输入长度 输出长度 填充内容
PKCS1 keySize - 11 keySize 随机数
NONE keySize - 1 keySize 00

有的文章说 padding 为 NONE 是的最大输入长度为 keySize,其实这样是有风险的。若是明文长度跟密钥长度同样的话,明文就有可能大于模数,这样在加密的时候就会出错。因此这里建议 padding 为 NONE 是明文的分段长度取 keySize - 1

分段加密以后就要分段解密了,在实际的RSA加密中,加密出来的密文老是等于密钥的长度,因此在分段解密的时候密文的分段大小直接取密钥长度。

三、填充模式

RSA在实际应用为了提升安全性防范各类攻击,在加解密过程当中都须要添加必定的随机因素。为了让同一明文每次加密产生的密文都不同,加密前先填充一部分随机数,这个不止RSA有,DES等对称加密也都有,称为padding。加密标准里有各类类型的padding标准,好比PCKS1。

对于PKCS1,这个填充格式会要求每次加密的数据比密钥长度短至少11个字节(keySize - 11),填充格式以下:

PS 为随机填充数,M为明文

00 02 | PS | 00 | M     (公钥加密)
00 01 | PS | 00 | M     (私钥加密)
复制代码

以 00 开头填充同时也保证了待加密数据不会大于密钥的模数。

还有一个比较经常使用的就是None(不填充),若是明文比密钥短的话会在明文的前面填充零(0)

0000 | M
复制代码

Demo传送门

相关文章
相关标签/搜索