密碼學在上世紀70年代之前,發展比較緩慢,主要以對稱加密的方式進行,即加密和解密所用的是同一套規則,加密規則在傳遞過程當中容易泄露,也就很容易被破解;1976年美國兩位數學家迪菲、赫爾曼提出「迪菲赫爾曼密鑰交換」算法,開啓密碼學研究的新方向;1977年三位麻省理工學院的數學家就一塊兒設計了一種非對稱加密算法,RSA算法加密。算法
1、 RSA 深刻理解
(一)RSA 數學原理
RSA 非對稱加密(現代加密算法),須要兩個密鑰,公開密鑰簡稱公鑰(publickey)私有密鑰簡稱私鑰(privatekey);公鑰加密,私鑰解密;私鑰加密,公鑰解密; 如下是RSA公式推導步驟: 一、歐拉函數 任一正整數n,小於等於n且能與n互質的正整數個數φ(n);安全
- 歐拉函數特色:
- 1.當n是質數時,φ(n) = n -1;
- 2.若是n能夠分解成兩個互質的整數之積,如 :n=A*B,則:φ(n) = φ(A)*φ(B);
- 根據以上兩點獲得:若是N是兩個互質的質數P1和P2之,則:φ(N) = φ(P1)φ(P2) = (P1-1)(P2-1);
二、歐拉定理 若是兩個正整數m和n互質,那麼m的φ(n)次方減去1,能夠被n整除,即bash
三、費馬小定理 歐拉定理的特殊狀況:若是兩個正整數m和n互質,且n爲質數,則φ(n) = n-1;
四、模反元素
五、迪菲赫爾曼密鑰交換
- 1.密鑰交換場景
- 2.密鑰交換原理 結合歐拉定理和模反元素,當同時知足①m<n,且②d是e相對於φ(n)的模反元素時,如下結果成立:
-
- RSA 算法
(二)OpenSSL 使用 RSA
OpenSSL 中 RSA經常使用的指令有如下幾種:服務器
命令 |
含義 |
genrsa |
生成並輸入一個RSA私鑰 |
rsautl |
使用RSA密鑰進行加密,解密、簽名和驗證等運算 |
rsa |
處理RSA密鑰的格式轉換等問題 |
一、生成RSA私鑰,密鑰長度爲1024 函數
二、從私鑰中提取公鑰
三、生成以下文件
四、將私鑰轉換成爲明文
五、經過公鑰加密數據,私鑰解密數據
六、經過私鑰加密數據,公鑰解密數據
2、 HASH算法與對稱加密
(一)HASH算法
Hash,通常翻譯作「散列」,也有直接音譯爲「哈希」的,就是把任意長度的輸入經過散列算法變換成固定長度的輸出,該輸出就是散列值。這種轉換是一種壓縮映射,也就是,散列值的空間一般遠小於輸入的空間,不一樣的輸入可能會散列成相同的輸出,因此不可能從散列值來肯定惟一的輸入值。簡單的說就是一種將任意長度的消息壓縮到某一固定長度的消息摘要的函數。測試
一、Hash的特色
-
- 無限多的數據加密獲得有限數目的表現形式,必定有一個或多個數據有相同的哈希值,叫作散列的碰撞;
二、Hash的用途
- 用戶密碼的加密
- 一、MD5,sha1,sha256,sha512等等,CMD5可根據存儲記錄(key-value)解密;
- 二、加鹽加密 壞處:鹽(是固定的)一旦泄露,同樣能夠CMD5解密,就不安全了,Hash加密的命令以下:
- md5 -s "string"
- echo -n "string" | openssl sha1 / echo -n "string" | openssl dgst sha1
- echo -n "string" | openssl sha256
- echo -n "string" | openssl sha512
- 三、HMAC 加密方案:a.使用一個密鑰加密,而且作了兩次散列 b.在實際開發中,密鑰來自於服務器
- 1.註冊:
- i.用戶輸入帳號或者帳戶名,服務器對帳號進行驗證是否可用,可用時隨機生成key返回給客戶端,客戶端存儲key;
- ii.客戶端拿到「key+用戶密碼」,進行HMAC拿到哈希值「hmac」,客戶端將「帳號+hmac」發送給服務器,服務器存儲「帳號+key+hmac」;
- iii.換設備登陸時:
- 輸入帳號密碼登陸時,檢測本地是否有相應key;
- 向服務器索要key,服務器對當前設備進行權限驗證,有權限發送key,無權限,須要原設備受權,受權成功發送key;
- 客戶端拿到key,進行登陸,登陸成功,保存key,登陸失敗,不保存key;
- 2.登陸:防止「帳號+hmac」被攔截時,被惡意登陸;
- i.註冊邏輯不變,服務器仍保存「帳號+key+hmac」;
- ii.登陸時用「(hmac+時間戳(到分鐘)).md5+帳號」,進行登陸;
- iii.服務器用「hmac+(當前時間(到分鐘)?-1)」方式進行驗證,有限時間(00:01:00-00:01:59)內有效;
- 3.相應加密命令:
- echo -n "string" | openssl dgst -md5 -hmac "key" --計算HMAC MD5散列結果
- echo -n "string" | openssl sha1 -hmac "key" --計算HMAC SHA1散列結果
- echo -n "string" | openssl sha256 -hmac "key" --計算HMAC SHA256散列結果
- echo -n "string" | openssl sha512 -hmac "key" --計算HMAC SHA512散列結果
- 搜索引擎 - 模糊搜索
- 版權
- 相同的二進制文件hash值相同;
- 複製,修改文件格式,不改變文件的二進制,hash值相同;
- 壓縮,base64改變文件二進制,所得hash值天然不一樣;
- 數字簽名
- 對傳輸的明文數據進行Hash獲得hash值;
- 利用RSA公鑰對hash值進行加密,獲得RSA密文,將密文和明文一塊兒傳輸給服務器;
- 服務器用RSA私鑰進行解密,獲得hash值,並對傳輸的明文數據進行相同算法的Hash獲得hash1值,並對hash和hash1匹配進行數據識別,相同時,說明數據正常,沒有被改動;
(二)對稱加密(傳統加密算法)
一、常見算法
- DES 數據加密標準(用得少,強度低)
- 3DES 使用3個密鑰,對相同的數據執行3次加密(沒人用,太麻煩,不容易管理)
- AES 高級加密標準
二、應用模式
- ECB(Electronic Code Book):電子密碼本模式。每一塊數據,獨立加密。
- 最基本的加密模式,也就是一般理解的加密,相同的明文將永遠加密成相同的密文,無初始向量,容易受到密碼本重放攻擊,通常狀況下不多用。
- CBC(Cipher Block Chaining):密碼分組連接模式。使用一個密鑰和一個初始化向量[IV]對數據執行加密。
- 明文被加密前要與前面的密文進行異或運算後再加密,所以只要選擇不一樣的初始向量,相同的密文加密後會造成不一樣的密文,這是目前應用最普遍的模式。CBC加密後的密文是上下文相關的,但明文的錯誤不會傳遞到後續分組,但若是一個分組丟失,後面的分組將所有做廢(同步錯誤)。
- CBC能夠有效的保證密文的完整性,若是一個數據塊在傳遞是丟失或改變,後面的數據將沒法正常解密。
三、終端測試指令
-
1.DES加解密
- DES(ECB)加密
- $ echo -n hello | openssl enc -des-ecb -K 616263 -nosalt | base64
- DES(ECB)解密
- $ echo -n HQr0Oij2kbo= | base64 -d | openssl enc -des-ecb -K 616263 -nosalt -d
- DES(CBC)加密
- $ echo -n hello | openssl enc -des-cbc -iv 0102030405060708 -K 616263 -nosalt | base64
- DES(CBC)解密
- $ echo -n alvrvb3Gz88= | base64 -d | openssl enc -des-cbc -iv 0102030405060708 -K 616263 -nosalt -d
-
2.AES加解密
- AES(ECB)加密
- $ echo -n hello | openssl enc -aes-128-ecb -K 616263 -nosalt | base64
- AES(ECB)解密
- $ echo -n d1QG4T2tivoi0Kiu3NEmZQ== | base64 -d | openssl enc -aes-128-ecb -K 616263 -nosalt -d
- AES(CBC)加密
- $ echo -n hello | openssl enc -aes-128-cbc -iv 0102030405060708 -K 616263 -nosalt | base64
- AES(CBC)解密
- $ echo -n u3W/N816uzFpcg6pZ+kbdg== | base64 -d | openssl enc -aes-128-cbc -iv 0102030405060708 -K 616263 -nosalt -d
四、CCCrypt函數分析
/**CCCrypt 對稱加密算法的核心函數(加密/解密)
CCCrypt(CCOperation op, CCAlgorithm alg, CCOptions options, const void *key, size_t keyLength, const void *iv, const void *dataIn, size_t dataInLength, void *dataOut, size_t dataOutAvailable, size_t *dataOutMoved);
參數:
一、 op kCCEncrypt 加密/kCCDecrypt 解密
二、 alg 加密算法、默認的 AES/DES
三、options 加密方式的選項
kCCOptionPKCS7Padding | kCCOptionECBMode;//ECB加密!
kCCOptionPKCS7Padding;//CBC 加密!
四、key 加密密鑰
五、keyLength 密鑰長度
六、iv 初始化向量,ECB 不須要指定
七、dataIn 加密的數據
八、dataInLength 加密的數據長度
九、dataOut 緩衝區(地址),存放密文的
十、dataOutAvailable 緩衝區的大小
十一、dataOutMoved 加密結果大小
*/
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
self.algorithm,
option,
cKey,
self.keySize,
cIv,
[data bytes],
[data length],
buffer,
bufferSize,
&decryptedSize);
複製代碼
-
2.利用CCCrypt函數動態調試獲取加密內容
- 下符號斷點
- 用寄存器register獲取存儲在其中的參數地址
register read x6
- 讀取地址中數據
p (char *) 0x7fff5103219e