數據加密: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傳送門

相關文章
相關標籤/搜索