RSA算法
是最廣爲使用的「非對稱加密算法
」,基本上只要有計算機網絡的地方,就有RSA算法。 這種算法很是可靠,密鑰越長,它就越難破解。根據報道,目前被破解的最長RSA密鑰是768個二進制位。也就是說,長度超過768位的密鑰,還沒法破解(至少沒人公開宣佈)。 所以能夠認爲,1024位的RSA密鑰基本安全,2048位的密鑰極其安全。RSA是由Rivest、Shamir 和 Adleman三位數學家1977年提出的加密算法,因此以他們首字母命名。html
理解RSA
首先要理解非對稱加密
:git
公鑰
和私鑰
組成,公鑰和私鑰是按照必定數學算法生成的。公鑰是公開的,任何人均可以獲取。私鑰是保密的,只有擁有者才能使用。RSA加密在iOS
中常常用到,常見場景是加密用戶輸入的密碼發送給後臺,固然爲了避免泄露用戶密碼,通常都是將密碼進行MD5加鹽編碼後再用RSA加密給後臺,這樣即便被破解,也不會泄露用戶輸入的密碼。github
App->>Server: App請求「公鑰」
Server->> App: Server返回「公鑰」
App->> Server: App用公鑰加密「密碼」發送
Server->> App: Server解密正確返回數據
複製代碼
注意: 通常是後臺從密鑰池中選取一對公私鑰,把公鑰發送給客戶端,客戶端加密密碼等機密信息後發送給後臺,後臺使用私鑰解密獲取加密的內容。算法
防反編譯: 密碼密鑰等信息通常不存在客戶端,防止被反編譯。數據庫
耗時操做: 生成公私鑰是耗時操做,後臺通常會提早生成多對公私鑰保存到數據庫中,使用的時候隨機取出一對,使用並記錄使用的那一對便可。安全
文件格式: 後臺生成.der和.p12後綴格式的文件,其中der格式的文件存放的是公鑰(Public key)用於加密,p12格式的文件存放的是私鑰(Private key)用於解密。後臺能夠從.der文件中讀出公鑰,轉化爲JSON字符串格式發送給客戶端,也能夠直接發送後綴名爲.der格式公鑰文件,客戶端下載後使用。服務器
iOS生成公私鑰對: 至於iOS端生成RSA公私鑰,須要集成openssl庫,具體Google百度吧。網絡
加解密失敗: 若是與後臺聯調的時候加解密失敗,注意一下密鑰格式(分爲pkcs8和pkcs1)。例如Mac下生成的給iOS使用公私鑰文件.der和.p12,密鑰編碼格式爲pkcs1;而Java後臺使用的.pem文件格式的公私鑰,編碼格式爲pkcs8,使用的時候須要轉換格式。函數
Wiki百科: 對極大整數作因數分解的難度決定了RSA算法的可靠性。換言之,對一極大整數作因數分解愈困難,RSA算法愈可靠。編碼
假若有人找到一種快速因數分解的算法,那麼RSA的可靠性就會極度降低。但找到這樣的算法的可能性是很是小的。今天只有短的RSA密鑰纔可能被暴力破解。到目前爲止,世界上尚未任何可靠的攻擊RSA算法的方式。
只要密鑰長度足夠長,用RSA加密的信息其實是不能被解破的。
PS:假設m爲要傳遞的密文,mod爲求餘,N、e、d都是已知的
若是要加密大於N的數據怎麼辦? 有兩種解決方法:
用戶密碼/交易密碼
發送給服務器客戶端向服務器請求
RSA公鑰
→服務器
→ 返給客戶端一個NSString
格式的RSA公鑰 → 客戶端用RSA公鑰字符串
加密密碼
發送給服務器 → 服務器用RSA私鑰解密並覈對密碼
→ 覈對密碼是否正確,並返回客戶數據給客戶端
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDTbZ6cNH9 PgdF60aQKveLz3FTalyzHQwbp601y77SzmGHX3F5NoVUZbd K7UMdoCLK4FBziTewYD9DWvAErXZo9BFuI96bAop8wfl1Vk ZyyHTcznxNJFGSQd/B70/ExMgMBpEwkAAdyUqIjIdVGh1FQ K/4acwS39YXwbS+IlHsPSQIDAQAB
但因爲含有/+=\n
等特殊字符串,網絡傳輸過程當中致使轉義,進而致使加密解密不成功,解決辦法是進行URL特殊符號編碼解碼(百分號轉義);具體示例,在Demo中有示例,文章最下方有Demo連接。
//----------------------RSA加密示例------------------------
//原始數據,要加密的字符串
NSString *originalString = @"這是一段將要使用'祕鑰字符串'進行加密的字符串!";
//使用字符串格式的公鑰私鑰加密解密, RSAPublickKey爲公鑰字符串(NSString格式)
NSString *encryptStr = [RSAEncryptor encryptString:originalString publicKey:RSAPublickKey];
NSLog(@"加密前:%@", originalString);
NSLog(@"加密後:%@", encryptStr);
//用私鑰解密,RSAPrivateKey爲私鑰字符串(NSString格式)
NSString *decryptString = [RSAEncryptor decryptString:encryptStr privateKey:RSAPrivateKey];
NSLog(@"解密後:%@",decryptString);
複製代碼
// RSA加密封裝類
//注意:若是使用,須要打開鑰匙串;由於iOS不支持直接使用字符串格式的公鑰進行加密,轉換爲文件後可以使用
#import <Foundation/Foundation.h>
@interface RSAEncryptor : NSObject
/**
* 加密方法
*
* @param str 須要加密的字符串
* @param path '.der'格式的公鑰文件路徑
*/
+ (NSString *)encryptString:(NSString *)str publicKeyWithContentsOfFile:(NSString *)path;
/**
* 解密方法
*
* @param str 須要解密的字符串
* @param path '.p12'格式的私鑰文件路徑
* @param password 私鑰文件密碼
*/
+ (NSString *)decryptString:(NSString *)str privateKeyWithContentsOfFile:(NSString *)path password:(NSString *)password;
/**
* 加密方法
*
* @param str 須要加密的字符串
* @param pubKey 公鑰字符串
*/
+ (NSString *)encryptString:(NSString *)str publicKey:(NSString *)pubKey;
/**
* 解密方法
*
* @param str 須要解密的字符串
* @param privKey 私鑰字符串
*/
+ (NSString *)decryptString:(NSString *)str privateKey:(NSString *)privKey;
@end
複製代碼
若是您以爲有所幫助,請在RSADemo上賞個Star ⭐️,您的鼓勵是我前進的動力