iOS 上 Security.framework 為我們提供了安全方面相關(guān)的 API。
成都創(chuàng)新互聯(lián)公司是一家集網(wǎng)站建設(shè),綏芬河企業(yè)網(wǎng)站建設(shè),綏芬河品牌網(wǎng)站建設(shè),網(wǎng)站定制,綏芬河網(wǎng)站建設(shè)報價,網(wǎng)絡(luò)營銷,網(wǎng)絡(luò)優(yōu)化,綏芬河網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強企業(yè)競爭力。可充分滿足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時我們時刻保持專業(yè)、時尚、前沿,時刻以成就客戶成長自我,堅持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實用型網(wǎng)站。
由于在項目開發(fā)中,一般使用服務(wù)器提供的密鑰對,在本地調(diào)試時可使用 openssl 生成
在加密過程之前,我們需要先獲取公鑰進(jìn)行存儲,這里是通過 .der 文件 加載到 類型為 SecKeyRef 的公鑰數(shù)據(jù),并進(jìn)行存儲。
將.p12 私鑰數(shù)據(jù)獲取,并對其存儲。
首先在工程中 引入 openssl ,openssl 是一個開源庫,我們可以使用 OpenSSL-Universal ,這個倉庫一直在維護(hù),支持 靜態(tài)庫、framework、Cocoapods等等方式引入工程。
RSA加密以及解密實現(xiàn)步驟:
1、使用openssl生成密匙對。
代碼如下:(代碼源于github開源社區(qū))
#!/usr/bin/env?bash??
echo?"Generating?RSA?key?pair?..."??
echo?"1024?RSA?key:?private_key.pem"??
openssl?genrsa?-out?private_key.pem?1024??
echo?"create?certification?require?file:?rsaCertReq.csr"??
openssl?req?-new?-key?private_key.pem?-out?rsaCertReq.csr??
echo?"create?certification?using?x509:?rsaCert.crt"??
openssl?x509?-req?-days?3650?-in?rsaCertReq.csr?-signkey?private_key.pem?-out?rsaCert.crt??
echo?"create?public_key.der?For?IOS"??
openssl?x509?-outform?der?-in?rsaCert.crt?-out?public_key.der??
echo?"create?private_key.p12?For?IOS.?Please?remember?your?password.?The?password?will?be?used?in?iOS."??
openssl?pkcs12?-export?-out?private_key.p12?-inkey?private_key.pem?-in?rsaCert.crt??
echo?"create?rsa_public_key.pem?For?Java"??
openssl?rsa?-in?private_key.pem?-out?rsa_public_key.pem?-pubout??
echo?"create?pkcs8_private_key.pem?For?Java"??
openssl?pkcs8?-topk8?-in?private_key.pem?-out?pkcs8_private_key.pem?-nocrypt??
echo?"finished."
2、加載證書后即可進(jìn)行加密算法。
代碼:
RSAEncryptor?*rsa?=?[[RSAEncryptor?alloc]?init];??
NSLog(@"encryptor?using?rsa");??
NSString?*publicKeyPath?=?[[NSBundle?mainBundle]?pathForResource:@"public_key"?ofType:@"der"];??
NSLog(@"public?key:?%@",?publicKeyPath);??
[rsa?loadPublicKeyFromFile:publicKeyPath];??
NSString?*securityText?=?@"hello?~";??
NSString?*encryptedString?=?[rsa?rsaEncryptString:securityText];??
NSLog(@"encrypted?data:?%@",?encryptedString);
對應(yīng)解密代碼:
NSLog(@"decryptor?using?rsa");??
[rsa?loadPrivateKeyFromFile:[[NSBundle?mainBundle]?pathForResource:@"private_key"?ofType:@"p12"]?password:@"123456"];??
NSString?*decryptedString?=?[rsa?rsaDecryptString:encryptedString];??
NSLog(@"decrypted?data:?%@",?decryptedString);
RSA基本原理:
RSA使用"秘匙對"對數(shù)據(jù)進(jìn)行加密解密.在加密解密數(shù)據(jù)前,需要先生成公鑰(public key)和私鑰(private key)。
公鑰(public key): 用于加密數(shù)據(jù). 用于公開, 一般存放在數(shù)據(jù)提供方, 例如iOS客戶端。
私鑰(private key): 用于解密數(shù)據(jù). 必須保密, 私鑰泄露會造成安全問題。
首先確認(rèn)你要加密的數(shù)據(jù)有多大,如果比較大建議先使用對稱算法進(jìn)行加密,將對稱算法的密鑰使用RSA加密即可。
現(xiàn)在定義:
你所拿到的公鑰模為 N,指數(shù)為E
N的位長度為 len(N)
N占用的字節(jié)數(shù)為 k = (len(N)+7)/8
要加密的數(shù)據(jù)為D (可以是你原始的數(shù)據(jù)或者對稱算法密鑰)
如果你的加密數(shù)據(jù)比較小的話也可以直接進(jìn)行RSA加密,比較小的意思為:被加密數(shù)據(jù)的長度必須能夠滿足填充條件,如果采用PKCS1_1.5的填充方式,D占用的字節(jié)要小于 k-11
運算過程很簡單: 將D進(jìn)行填充到D1, 要求D1所占用的字節(jié)數(shù)為 k (即同N的長度相同)
則計算密文E的過程為 DE = (D1 ^ E) % N ( ^ 表示指數(shù)運算)
在程序中實現(xiàn)建議你采用一些現(xiàn)成的庫,如果有OpenSSL則可以網(wǎng)上搜索一下,資料應(yīng)該不少。
如果沒有的話可以直接引入一些大數(shù)計算的庫直接進(jìn)行模指運算(別分開,太慢)。
1、加密解密的第一步是生成公鑰、私鑰對,私鑰加密的內(nèi)容能通過公鑰解密(反過來亦可以)下載開源RSA密鑰生成工具openssl(通常Linux系統(tǒng)都自帶該程序),解壓縮至獨立的文件夾,進(jìn)入其中的bin目錄,執(zhí)行以下命令:代碼如下: openssl genrsa -out rsa_private_key.pem 1024openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt -out private_key.pemopenssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem 第一條命令生成原始 RSA私鑰文件 rsa_private_key.pem,第二條命令將原始 RSA私鑰轉(zhuǎn)換為 pkcs8格式,第三條生成RSA公鑰 rsa_public_key.pem從上面看出通過私鑰能生成對應(yīng)的公鑰,因此我們將私鑰private_key.pem用在服務(wù)器端,公鑰發(fā)放給android跟ios等前端2、php中用生成的公鑰、私鑰進(jìn)行加密解密,直接上代碼代碼如下: $fp=fopen("rsa/rsa_private_key.pem","r"); //你的私鑰文件路徑$private_key=fread($fp,8192);fclose($fp);$fp1=fopen("rsa/rsa_public_key.pem","r"); //你的公鑰文件路徑$public_key=fread($fp1,8192);fclose($fp1);//echo $private_key; $pi_key=openssl_pkey_get_private($private_key);//這個函數(shù)可用來判斷私鑰是否是可用的,可用返回資源id Resource id $pu_key=openssl_pkey_get_public($public_key );//這個函數(shù)可用來判斷公鑰是否是可用的print_r($pi_key);echo "n"; echo "br";print_r($pu_key);echo "n"; echo "br";echo "hr";$data='php ras加密算法';$encrypted = ""; $decrypted = ""; echo "加密的源數(shù)據(jù):".$data."n"; echo "br";echo "private key encrypt:n"; echo "br";openssl_private_encrypt($data,$encrypted,$pi_key);//私鑰加密 $encrypted = base64_encode($encrypted);//加密后的內(nèi)容通常含有特殊字符,需要編碼轉(zhuǎn)換下,在網(wǎng)絡(luò)間通過url傳輸時要注意base64編碼是否是url安全的 echo '私鑰加密后:'.$encrypted."n"; echo "br";echo "br";echo "public key decrypt:n"; echo "br";openssl_public_decrypt(base64_decode($encrypted),$decrypted,$pu_key);//私鑰加密的內(nèi)容通過公鑰可用解密出來 echo '公鑰解密后:'.$decrypted."n"; echo "br";echo "hr";echo "public key encrypt:n"; echo "br";openssl_public_encrypt($data,$encrypted,$pu_key);//公鑰加密 $encrypted = base64_encode($encrypted); echo $encrypted,"n"; echo "br";echo "private key decrypt:n"; echo "br";openssl_private_decrypt(base64_decode($encrypted),$decrypted,$pi_key);//私鑰解密 echo $decrypted,"n"; echo "br"; PHP的RSA配置常見問題:●PHP開發(fā)語言的代碼示例中openssl文件夾中的3個DLL文件用法1、如果你的系統(tǒng)是windows系統(tǒng),且system32文件目錄下沒有l(wèi)ibeay32.dll、ssleay32.dll這兩個文件那么需要拷貝這兩個文件到system32文件目錄。2、如果您的php安裝目錄下(phpext)中沒有php_openssl.dll那么請把php_openssl.dll放在這個文件夾中喜歡加密解密的小伙伴一定要好好看看這篇文章,受益匪淺。。。
要講逆向,那么肯定少不了密碼學(xué),因為所有的逆向(攻防)都是對已加密的數(shù)據(jù)進(jìn)行解密。所以我們必須初步了解加密的方式有哪些,畢竟知己知彼,才能百戰(zhàn)百勝。
接下來,我將從以下四方面來講述密碼學(xué)相關(guān)的內(nèi)容:
1、什么是密碼學(xué)
2、RSA數(shù)學(xué)原理
3、RSA終端命令
4、總結(jié)
密碼學(xué)的歷史大致可以追溯到兩千年前,相傳古羅馬名將凱撒大帝為了防止敵方截獲情報,用密碼傳送情報。凱撒的做法很簡單,就是對二十幾個羅馬字母建立一張對應(yīng)表。這樣,如果不知道密碼本,即使截獲一段信息也看不懂。
從凱撒大帝時代到上世紀(jì)70年代這段很長的時間里,密碼學(xué)的發(fā)展非常的緩慢,因為設(shè)計者基本上靠經(jīng)驗。沒有運用數(shù)學(xué)原理。
在1976年以前,所有的加密方法都是同一種模式:加密、解密使用同一種算法。在交互數(shù)據(jù)的時候,彼此通信的雙方就必須將規(guī)則告訴對方,否則沒法解密。那么加密和解密的規(guī)則(簡稱密鑰),它保護(hù)就顯得尤其重
要。傳遞密鑰就成為了最大的隱患。這種加密方式被成為對稱加密算法(symmetric encryption algorithm)。
1976年,兩位美國計算機學(xué)家 迪菲(W.Diffie)、赫爾曼( M.Hellman ) 提出了一種嶄新構(gòu)思,可以在不直接傳遞密鑰的情況下,完成密鑰交換。這被稱為“迪菲赫爾曼密鑰交換”算法。開創(chuàng)了密碼學(xué)研究的新方向。
1977年三位麻省理工學(xué)院的數(shù)學(xué)家 羅納德·李維斯特(Ron Rivest)、阿迪·薩莫爾(Adi Shamir)和倫納德·阿德曼(Leonard Adleman)一起設(shè)計了一種算法,可以實現(xiàn)非對稱加密。這個算法用他們?nèi)齻€人的名字命名,叫做RSA算法。
也就是說「迪菲赫爾曼密鑰交換」在密碼學(xué)歷史的車輪中成為了一個轉(zhuǎn)折點。
咱們這里先把所有需要用到的公式定理列出來:
1、取模運算
2、歐拉函數(shù)φ
3、歐拉定理,費馬小定理
4、模反元素
5、迪菲赫爾曼密鑰交換
取模運算(“Modulo Operation”)和取余運算(“Complementation ”)兩個概念有重疊的部分但又不完全一致。主要的區(qū)別在于對負(fù)整數(shù)進(jìn)行除法運算時操作不同。
在這列出各種負(fù)數(shù)情況的例子供大家理解:
7 mod 4 = 3(商 = 1 或 2,12,取商=1)
-7 mod 4 = 1(商 = -1 或 -2,-2-1,取商=-2)
7 mod -4 = -1(商 = -1或-2,-2-1,取商=-2)
-7 mod -4 = -3(商 = 1或2,12,取商=1)
函數(shù)值符號規(guī)律(余數(shù)的符號) mod(負(fù),正)=正 mod(正,負(fù))=負(fù)
結(jié)論:兩個整數(shù)求余時,其值的符號為除數(shù)的符號。
可以簡單理解為:
如果n可以分解為 兩個互質(zhì)(不一定是兩個質(zhì)數(shù)) 的數(shù)之積A和B,那么:
φ(n) = φ(A) * φ(B)
如果 A和B 又同時為質(zhì)數(shù),那么:
φ(n) = (A-1) * (B-1)
首先這里說一下,定制之所以是定理是被人證明過的,如何證明的不管,當(dāng)然你也可以增加去證明下,反正我不管(……%¥%……%……%),哈哈
如果m、n為正整數(shù),且m、n互質(zhì),那么:
如果n為質(zhì)數(shù),那么:
公式轉(zhuǎn)換:
如果兩個正整數(shù)e和x互質(zhì),那么一定可以找到整數(shù)d,使得 e*d-1 被x整除。那么d就是e對于x的“模反元素”。
如上圖:
客戶端持有一個隨機數(shù)13 ,服務(wù)端持有隨機數(shù)15,再選一對特殊的數(shù),3是17的原根(啥是 原根 ?)。
兩端交換的都是密文,就算中間被劫持,也不知道最后需要的傳輸?shù)膬?nèi)容是10
那么這個10就是最后真正的秘鑰。
證明過程
設(shè)
那么:
又由于上面模反元素 最后得出
所以得出最終結(jié)論:
這個公式也就是我們最后的RSA加密公式?。?!
其中:
補充:
1、n會非常大,長度一般為1024個二進(jìn)制位。(目前人類已經(jīng)分解的最大整數(shù),232個十進(jìn)制位,768個二進(jìn)制位)
2、由于需要求出φ(n),所以根據(jù)歐函數(shù)特點,最簡單的方式n 由兩個質(zhì)數(shù)相乘得到: 質(zhì)數(shù):p1、p2
Φ(n) = (p1 -1) * (p2 - 1)
3、最終由φ(n)得到e 和 d 。
總共生成6個數(shù)字:p1、p2、n、φ(n)、e、d
關(guān)于RSA的安全:
除了公鑰用到了n和e 其余的4個數(shù)字是不公開的。
目前破解RSA得到d的方式如下:
1、要想求出私鑰 d 。由于e d = φ(n) k + 1。要知道e和φ(n);
2、e是知道的,但是要得到 φ(n),必須知道p1 和 p2。
3、由于 n=p1*p2。只有將n因數(shù)分解才能算出。
由于Mac系統(tǒng)內(nèi)置OpenSSL(開源加密庫),所以我們可以直接在終端上使用命令來玩RSA. OpenSSL中RSA算法常用指令主要有三個:
1、由于RSA加密解密用的不是一套數(shù)據(jù),所以其保證了安全性。
2、由于私鑰過大,所以效率較低
3、如果有一天量子計算機被普及(計算速度極快),那么1024位已經(jīng)不足以讓RSA安全。