做網絡框架,勢必要與http請求打交道,那么加密策略也是各大公司必不可少的部分。這篇文章我來總結下我接觸過的加密算法和策略。
一、基礎
首先http協議本身存在安全性問題,主要為如下幾點:
-
數據隱私性
:通信使用明文、內容可能被竊取。 -
數據完整性
:無法證明報文完整性,內容可能遭篡改。 -
身份認證
:不驗證通信方身份,可能遭遇偽裝。
因此要解決這些問題,就引入了加密。那么目前加密主要分兩大類:
-
自定義
:說白了就是跟服務端約定好加解密方案和規則,對請求和響應進行加密,防止明文裸奔,同時做好完整性認證和身份認證。 -
三方
:用https,https在http基礎上增加了ssl加密層,對傳輸數據幫你做好了加解密,通過購買證書、添加證書記錄、頒發證書后上傳來完成域名https化就行。客戶端只需要配置下網絡庫去支持https,目前volley和okhttp都支持https。
二、加密算法
好,那么不管是自定義還是三方方案,都會用到加密算法,那么基本加密算法還是有必要了解下。
2.1 簽名和加密
A向B發送信息,數據簽名是讓B確認信息是A發送的,不是別人。而數據加密保證數據不能被除B之外的其他人獲取到。
2.2 加密算法
1)對稱性加密算法
加密和解密使用同一個密鑰(私鑰),信息接收雙方都需事先知道密匙和加解密算法。
AES 高級加密標準,又稱Rijndael加密法,是美國聯邦政府采用的一種區塊加密標準。
-
ECB模式 (Electronic Codebook Book)
將整個明文分成若干段相同的小段,然后對每一小段進行加密。 -
CBC模式(Cipher Block Chaining)
先將明文切分成若干小段,然后每一小段與初始塊或者上一段的密文段進行異或運算后,再與密鑰進行加密。
優點:加解密速度快、效率高。
缺點:對稱加密時,都需要使用其他人不知道的唯一秘鑰,密鑰數量巨大,管理和分發非常困難,秘鑰一旦泄露,加密信息就不安全了。
作用:對傳輸明文加解密。
2)非對稱加密算法
加密和解密所使用的不是同一個密鑰,通常有兩個密鑰,稱為"公鑰"和"私鑰",它們兩個必需配對使用,否則不能打開加密文件。雙方分別生成公私鑰,公鑰給對方,私鑰自己保留。拿對方的公鑰向對方發送加密信息,對方拿私鑰解密。
RSA 目前主流的非對稱加密算法。
優點:秘鑰管理方便,安全性高。
缺點:加解密過程復雜,耗時長,只適合對少量數據加密。
數據加密:任何發送方都可以用接收方的公鑰加密,接收方用對應的私鑰解密。
數據簽名:用發送方的私鑰加密,任何接收方都可以用發送方公鑰解密。
3)散列算法/哈希算法
一種單向加密算法,過程不可逆。
MD5 信息摘要算法。把任意數據轉換為定長(或限制長度)的數據,
SHA1 也是一種哈希算法,與md5類似。SHA1摘要比md5長32位,安全性更好,但是運算步驟要多一些,所以慢一些。
作用:進行一致性驗證、數字簽名、安全訪問認證。
4)密鑰交換方案
D-H 依賴的是:離散對數運算。
有兩個公開的數g和p,其中p為素數,g是p的一個元根。
甲:私鑰a A = g^a mod p 把A發給乙
乙:私鑰b B= g^b mod p 把B發給甲
甲:B^a mod p = Fkey
乙:A^b mod p =Skey
Fkey = Skey
只要私鑰不泄漏就行。
ECDH = ECC +DH https使用ECDH密鑰交換.
DH和ECDH的主要的作用就是在通信雙方發送一些公有參數,保留私有參數,而后通過一系列計算雙方都能夠得到一個一致的結果。而這個運算的逆運算復雜度過高,在有限時間內不可解(至少量子計算機問世以前不可解),以保證密鑰安全性。
5)其他算法
嚴格意義上不算加密。
Base64 一種編碼方式,用來將非ASCII字符的數據轉換成ASCII字符的一種轉換算法。
作用:便于網絡傳輸。
算法基本分這么四類,每一類都包含但不限于這么幾種,每類我只例舉了目前最為主流的方案,最個基本介紹。
三、加密策略
那么,介紹完加密算法,接下來談談目前主要使用的加密策略。
3.1 RSA+SHA1
用SHA算法進行簽名,用RSA算法進行加密。
加密流程:
1)利用私鑰將請求參數進行 SHA1withRSA 簽名即可。
/**
* 進行sha1 Rsa算法簽名
* @param str
* @param privateKey
* @return
*/
public static byte[] sha1WithRsa(String str, PrivateKey privateKey) {
try {
Signature signature = Signature.getInstance("SHA1withRSA");
signature.initSign(privateKey);
signature.update(str.getBytes());
return signature.sign();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (SignatureException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
}
return null;
}
2)加密完成開始打包參數。
主要玩的是這個類:/Android/sdk/sources/android-27/java/security/Signature.java
3.2 RSA+AES
使用RSA來首先傳輸AES的密鑰給對方,然后再使用AES來進行加密通訊。
加密流程:
1)將請求參數進行AES加密。
public static byte[] encryptByAes(String data, String pass, String init,
String mode) throws Exception {
String transformation;
//選擇CBC or ECB模式
if (mode.equals(Constant.ECODE_METHOD)) {
transformation = Constant.AES_TRANSFORMATION_CBC;
} else {
transformation = Constant.AES_TRANSFORMATION_ECB;
}
try {
Cipher cipher = Cipher.getInstance(transformation);
int blockSize = cipher.getBlockSize();
...
// 將隨機生成的密碼變成AES算法的私鑰
SecretKeySpec keyspec = new SecretKeySpec(hexString2Bytes(pass),
"AES");
// ECB don't need ivspec
IvParameterSpec ivspec = new IvParameterSpec(init.getBytes());
if (mode.equals(Constant.ECODE_METHOD)) {
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
} else {
cipher.init(Cipher.ENCRYPT_MODE, keyspec);
}
byte[] encrypted = cipher.doFinal(plaintext);
return encrypted;
} catch (Exception e) {
e.printStackTrace();
return new byte[0];
}
}
2)利用私鑰將AES加密后的結果進行RSA加密。
/**
* 進行Rsa算法加密
* @param data 需要加密的數據
* @param privateKey 加密所需要的私鑰
* @return
*/
public static byte[] encryptByRsa(String data, PrivateKey privateKey) {
try
Cipher cipher = Cipher.getInstance(Constant.RSA_TRANSFORMATION);
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
byte[] encryptData = cipher.doFinal(data.getBytes());
return encryptData;
} catch (Exception e) {
e.printStackTrace();
return new byte[0];
}
}
3)加密完成開始打包參數。
主要玩的是這個類:Android/sdk/sources/android-27/javax/crypto/Cipher.java
公司保密性原因,具體細節不便過多透露,這里了解個大概策略就行,具體加解密代碼網上應該能搜到一大堆。
3.3 數據簽名
這種方案就純跟服務端去自定義你們覺得合適的加密方式來滿足明文保密、明文完整性驗證和身份驗證的需要。
3.4 Https
HTTPS = HTTP+SSL(TLS)。
原本HTTP和TCP/UDP直接通信,而加了SSL后,就變成HTTP先和SSL通信,再由SSL和TCP/UDP通信。
HTTPS和HTTP的主要區別:
- https協議需要到ca申請證書,一般免費證書較少,需要一定費用。
- http是超文本傳輸協議,信息是明文傳輸,https則是具有安全性的ssl加密傳輸協議。
- HTTPS協議是由SSL+HTTP協議構建的可進行加密傳輸、身份認證的網絡協議,比http協議安全。
說白了,https就是在http協議層面幫你做了加密。
優點:加密傳輸、身份認證、安全性高。
缺點:
- HTTPS協議握手階段比較費時,會使頁面的加載時間延長,同時增加耗電;(這個沒驗證過具體程度)
- 證書需要一定費用。
- 加密和證書都依賴第三方,存在風險。
Https也是對稱加密和非對稱加密結合的方式。
https流程解析:
client -> http請求 ->server
server ->證書(公鑰、私鑰)->公鑰->client
client ->TLS驗證公鑰有效- 生成隨機數用公鑰加密生成私鑰 ->server
server->用隨機數私鑰對明文進行對稱加密 -> client
client ->隨機數私鑰對明文解密->server
各加密算法在https中的作用:
CA證書:由它生產的公鑰能確認服務端正確性,防止中間人攻擊。
AES:明文加密,但是加密效率高,但是密鑰不安全。
RSA:保證AES密鑰安全性。
DH/ECDH:向前安全。
注:只要 rsa 私鑰被破解了,就可以解開以前的信息的對稱密鑰,然后就破解了以前的信息。
而 DH 是當時 client 和 server 共同算出的對稱密鑰,即時 rsa 私鑰被破解,以往的信息仍然是安全的。