對於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
複製代碼