做網(wǎng)絡(luò)框架丁屎,勢必要與http請求打交道负饲,那么加密策略也是各大公司必不可少的部分。這篇文章我來總結(jié)下我接觸過的加密算法和策略谬哀。
一刺覆、基礎(chǔ)
首先http協(xié)議本身存在安全性問題,主要為如下幾點:
-
數(shù)據(jù)隱私性
:通信使用明文史煎、內(nèi)容可能被竊取。 -
數(shù)據(jù)完整性
:無法證明報文完整性驳糯,內(nèi)容可能遭篡改篇梭。 -
身份認證
:不驗證通信方身份,可能遭遇偽裝酝枢。
因此要解決這些問題恬偷,就引入了加密。那么目前加密主要分兩大類:
-
自定義
:說白了就是跟服務(wù)端約定好加解密方案和規(guī)則帘睦,對請求和響應(yīng)進行加密袍患,防止明文裸奔,同時做好完整性認證和身份認證竣付。 -
三方
:用https诡延,https在http基礎(chǔ)上增加了ssl加密層,對傳輸數(shù)據(jù)幫你做好了加解密古胆,通過購買證書肆良、添加證書記錄筛璧、頒發(fā)證書后上傳來完成域名https化就行∪鞘眩客戶端只需要配置下網(wǎng)絡(luò)庫去支持https夭谤,目前volley和okhttp都支持https。
二巫糙、加密算法
好朗儒,那么不管是自定義還是三方方案,都會用到加密算法参淹,那么基本加密算法還是有必要了解下醉锄。
2.1 簽名和加密
A向B發(fā)送信息,數(shù)據(jù)簽名是讓B確認信息是A發(fā)送的承二,不是別人榆鼠。而數(shù)據(jù)加密保證數(shù)據(jù)不能被除B之外的其他人獲取到。
2.2 加密算法
1)對稱性加密算法
加密和解密使用同一個密鑰(私鑰)亥鸠,信息接收雙方都需事先知道密匙和加解密算法妆够。
AES 高級加密標準,又稱Rijndael加密法负蚊,是美國聯(lián)邦政府采用的一種區(qū)塊加密標準神妹。
-
ECB模式 (Electronic Codebook Book)
將整個明文分成若干段相同的小段,然后對每一小段進行加密家妆。 -
CBC模式(Cipher Block Chaining)
先將明文切分成若干小段鸵荠,然后每一小段與初始塊或者上一段的密文段進行異或運算后,再與密鑰進行加密伤极。
優(yōu)點:加解密速度快蛹找、效率高。
缺點:對稱加密時哨坪,都需要使用其他人不知道的唯一秘鑰庸疾,密鑰數(shù)量巨大,管理和分發(fā)非常困難当编,秘鑰一旦泄露届慈,加密信息就不安全了。
作用:對傳輸明文加解密忿偷。
2)非對稱加密算法
加密和解密所使用的不是同一個密鑰金顿,通常有兩個密鑰,稱為"公鑰"和"私鑰"鲤桥,它們兩個必需配對使用揍拆,否則不能打開加密文件。雙方分別生成公私鑰芜壁,公鑰給對方礁凡,私鑰自己保留高氮。拿對方的公鑰向?qū)Ψ桨l(fā)送加密信息,對方拿私鑰解密顷牌。
RSA 目前主流的非對稱加密算法剪芍。
優(yōu)點:秘鑰管理方便,安全性高窟蓝。
缺點:加解密過程復(fù)雜罪裹,耗時長,只適合對少量數(shù)據(jù)加密运挫。
數(shù)據(jù)加密:任何發(fā)送方都可以用接收方的公鑰加密状共,接收方用對應(yīng)的私鑰解密。
數(shù)據(jù)簽名:用發(fā)送方的私鑰加密谁帕,任何接收方都可以用發(fā)送方公鑰解密峡继。
3)散列算法/哈希算法
一種單向加密算法,過程不可逆匈挖。
MD5 信息摘要算法碾牌。把任意數(shù)據(jù)轉(zhuǎn)換為定長(或限制長度)的數(shù)據(jù),
SHA1 也是一種哈希算法儡循,與md5類似舶吗。SHA1摘要比md5長32位,安全性更好择膝,但是運算步驟要多一些誓琼,所以慢一些。
作用:進行一致性驗證肴捉、數(shù)字簽名腹侣、安全訪問認證。
4)密鑰交換方案
D-H 依賴的是:離散對數(shù)運算齿穗。
有兩個公開的數(shù)g和p,其中p為素數(shù)筐带,g是p的一個元根。
甲:私鑰a A = g^a mod p 把A發(fā)給乙
乙:私鑰b B= g^b mod p 把B發(fā)給甲
甲:B^a mod p = Fkey
乙:A^b mod p =Skey
Fkey = Skey
只要私鑰不泄漏就行缤灵。
ECDH = ECC +DH https使用ECDH密鑰交換.
DH和ECDH的主要的作用就是在通信雙方發(fā)送一些公有參數(shù),保留私有參數(shù)蓝晒,而后通過一系列計算雙方都能夠得到一個一致的結(jié)果腮出。而這個運算的逆運算復(fù)雜度過高,在有限時間內(nèi)不可解(至少量子計算機問世以前不可解)芝薇,以保證密鑰安全性胚嘲。
5)其他算法
嚴格意義上不算加密。
Base64 一種編碼方式洛二,用來將非ASCII字符的數(shù)據(jù)轉(zhuǎn)換成ASCII字符的一種轉(zhuǎn)換算法馋劈。
作用:便于網(wǎng)絡(luò)傳輸攻锰。
算法基本分這么四類,每一類都包含但不限于這么幾種妓雾,每類我只例舉了目前最為主流的方案娶吞,最個基本介紹。
三械姻、加密策略
那么妒蛇,介紹完加密算法,接下來談?wù)勀壳爸饕褂玫募用懿呗浴?/p>
3.1 RSA+SHA1
用SHA算法進行簽名楷拳,用RSA算法進行加密绣夺。
加密流程:
1)利用私鑰將請求參數(shù)進行 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)加密完成開始打包參數(shù)欢揖。
主要玩的是這個類:/Android/sdk/sources/android-27/java/security/Signature.java
3.2 RSA+AES
使用RSA來首先傳輸AES的密鑰給對方陶耍,然后再使用AES來進行加密通訊。
加密流程:
1)將請求參數(shù)進行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加密后的結(jié)果進行RSA加密烈钞。
/**
* 進行Rsa算法加密
* @param data 需要加密的數(shù)據(jù)
* @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)加密完成開始打包參數(shù)。
主要玩的是這個類:Android/sdk/sources/android-27/javax/crypto/Cipher.java
公司保密性原因产上,具體細節(jié)不便過多透露棵磷,這里了解個大概策略就行,具體加解密代碼網(wǎng)上應(yīng)該能搜到一大堆晋涣。
3.3 數(shù)據(jù)簽名
這種方案就純跟服務(wù)端去自定義你們覺得合適的加密方式來滿足明文保密仪媒、明文完整性驗證和身份驗證的需要。
3.4 Https
HTTPS = HTTP+SSL(TLS)谢鹊。
原本HTTP和TCP/UDP直接通信算吩,而加了SSL后,就變成HTTP先和SSL通信佃扼,再由SSL和TCP/UDP通信偎巢。
HTTPS和HTTP的主要區(qū)別:
- https協(xié)議需要到ca申請證書,一般免費證書較少兼耀,需要一定費用压昼。
- http是超文本傳輸協(xié)議,信息是明文傳輸瘤运,https則是具有安全性的ssl加密傳輸協(xié)議窍霞。
- HTTPS協(xié)議是由SSL+HTTP協(xié)議構(gòu)建的可進行加密傳輸、身份認證的網(wǎng)絡(luò)協(xié)議拯坟,比http協(xié)議安全但金。
說白了,https就是在http協(xié)議層面幫你做了加密郁季。
優(yōu)點:加密傳輸冷溃、身份認證钱磅、安全性高。
缺點:
- HTTPS協(xié)議握手階段比較費時似枕,會使頁面的加載時間延長盖淡,同時增加耗電;(這個沒驗證過具體程度)
- 證書需要一定費用菠净。
- 加密和證書都依賴第三方禁舷,存在風(fēng)險。
Https也是對稱加密和非對稱加密結(jié)合的方式毅往。
https流程解析:
client -> http請求 ->server
server ->證書(公鑰牵咙、私鑰)->公鑰->client
client ->TLS驗證公鑰有效- 生成隨機數(shù)用公鑰加密生成私鑰 ->server
server->用隨機數(shù)私鑰對明文進行對稱加密 -> client
client ->隨機數(shù)私鑰對明文解密->server
各加密算法在https中的作用:
CA證書:由它生產(chǎn)的公鑰能確認服務(wù)端正確性,防止中間人攻擊攀唯。
AES:明文加密洁桌,但是加密效率高,但是密鑰不安全侯嘀。
RSA:保證AES密鑰安全性另凌。
DH/ECDH:向前安全。
注:只要 rsa 私鑰被破解了戒幔,就可以解開以前的信息的對稱密鑰吠谢,然后就破解了以前的信息。
而 DH 是當(dāng)時 client 和 server 共同算出的對稱密鑰诗茎,即時 rsa 私鑰被破解工坊,以往的信息仍然是安全的。