天天看點

編解碼和加密詳解

文章目錄

    • 1. 編碼和解碼(encode/decode)算法
      • 1.1 Base64算法
      • 1.2 壓縮算法
      • 1.3 Java序列化和反序列化
    • 2. 常見加密算法
      • 2.1 什麼是加密算法
      • 2.2 MD5算法
      • 2.3 SHA1算法
      • 2.4 HMAC算法
    • 3. 結論

1. 編碼和解碼(encode/decode)算法

簡單了解,編碼就是把資訊按照一定的規則進行組織,變換消息形式的過程,所謂解碼就是把收到的資訊按照一定的規則進行解析,并且這個規則往往是固定的,必須是編碼者和解碼者事先都知道或約定好的。常見的編碼手段有Base64和壓縮算法。

1.1 Base64算法

Base64最早起源于HTTP協定下的資料傳輸,由于HTTP協定是文本協定,是以在HTTP協定下傳輸二進制資料需要将二進制資料轉換為字元資料。然而直接轉換是不行的。因為網絡傳輸隻能傳輸可列印字元(在ASCII碼中規定,0~31、127這33個字元屬于控制字元,32~126這95個字元屬于可列印字元,也就是說網絡傳輸隻能傳輸這95個字元)。使用Base64就是将不在這些字元範圍内的其他字元轉換為可列印字元。

具體的64位的映射關系如下圖:

編解碼和加密詳解

Base64算法的固定規則:因為索引最大63,是以Base64的索引最多隻占6個Bit,但是ASCII碼字元需要8個Bit來表示,是以,Base64按照三個一組,會把連續的3個位元組變成4個位元組,然後每個位元組補齊高位的2個0,這樣38就等于46了,也就是說,轉換後的字元串理論上将要比原來的長1/3。同時Base64規定,當需要轉換的字元不是3的倍數時,一律采用補0的方式湊足3的倍數。

百度百科的例子介紹很形象
轉換前 10101101,10111010,01110110
轉換後 00101011, 00011011 ,00101001 ,00110110
十進制 43 27 41 54
對應碼表中的值 r b p 2
是以上面的24位編碼,編碼後的Base64值為 rbp2
解碼同理,把 rbq2 的二進制位連接配接上再重組得到三個8位值,得出原碼。
(解碼隻是編碼的逆過程,有關MIME的RFC還有很多,如果需要詳細情況請自行查找。)
第一個位元組,根據源位元組的第一個位元組處理。
規則:源第一位元組右移兩位,去掉低2位,高2位補零。
既:00 + 高6位
第二個位元組,根據源位元組的第一個位元組和第二個位元組聯合處理。
規則如下,第一個位元組高6位去掉然後左移四位,第二個位元組右移四位
即:源第一位元組低2位 + 源第2位元組高4位
第三個位元組,根據源位元組的第二個位元組和第三個位元組聯合處理,
規則第二個位元組去掉高4位并左移兩位(得高6位),第三個位元組右移6位并去掉高6位(得低2位),相加即可
第四個位元組,規則,源第三位元組去掉高2位即可
//用更接近于程式設計的思維來說,編碼的過程是這樣的:
//第一個字元通過右移2位獲得第一個目标字元的Base64表位置,根據這個數值取到表上相應的字元,就是第一//個目标字元。
//然後将第一個字元與0x03(00000011)進行與(&)操作并左移4位,接着第二個字元右移4位與前者相或(|),即獲得第二個目标字元。
//再将第二個字元與0x0f(00001111)進行與(&)操作并左移2位,接着第三個字元右移6位與前者相或(|),獲得第三個目标字元。
//最後将第三個字元與0x3f(00111111)進行與(&)操作即獲得第四個目标字元。
//在以上的每一個步驟之後,再把結果與 0x3F 進行 AND 位操作,就可以得到編碼後的字元了。
           

java使用Base64進行編碼和解碼:

//編碼
java.util.Base64.getEncoder().encodeToString("aaaa".getBytes("UTF-8"));
//解碼
byte[] decode = Base64.getDecoder().decode(encode);
//轉換為String
String aaaa = new String(decode, "UTF-8")
           

1.2 壓縮算法

壓縮算法是指在不丢失資訊的前提下,縮減資料量以減少存儲空間,提高傳輸、存儲和處理效率的一種技術方法。或者是按照一定的算法對資料進行重新組織,減少資料的備援和存儲的空間,在電子與通信領域也常被稱為信号編碼。

消息壓縮的基本原理是霍夫曼樹,實作上有很多種,比如常見的gzip、LZW壓縮、lz4、遊程編碼(RLC)、snappy等等,使用過程中根據業務場景,從性能、壓縮率等方向去選擇合适的。

霍夫曼樹和常見的壓縮算法詳細介紹

壓縮算法比較

1.3 Java序列化和反序列化

Java序列化就是指把Java對象轉換為位元組序列的過程,反之,反序列化就是指把位元組序列恢複為Java對象的過程。其作用就是在跨程序跨服務的資料傳輸過程中,進行對象狀态的儲存和重建。

java序列化詳解

2. 常見加密算法

2.1 什麼是加密算法

加密算法分對稱加密和非對稱加密,其中對稱加密算法的加密與解密 密鑰相同,非對稱加密算法的加密密鑰與解密 密鑰不同,此外,還有一類 不需要密鑰 的 雜湊演算法。

常見的 對稱加密 算法主要有 DES、3DES、AES 等,常見的 非對稱算法 主要有 RSA、DSA 等,雜湊演算法 主要有 SHA-1、MD5 等。

2.2 MD5算法

MD5 用的是 哈希函數,它的典型應用是對一段資訊産生 資訊摘要,以 防止被篡改。嚴格來說,MD5 不是一種 加密算法 而是 摘要算法。無論是多長的輸入,MD5 都會輸出長度為 128bits 的一個串 (通常用 16 進制 表示為 32 個字元)。

java.security.MessageDigest.getInstance("MD5").digest(content);
           

2.3 SHA1算法

SHA1 和 MD5類似,也是一種較流行的消息摘要算法,它比 MD5 的安全性更強。對于長度小于 2 ^ 64 位的消息,SHA1 會産生一個 160 位的 消息摘要。基于 MD5、SHA1 的資訊摘要特性以及 不可逆 (一般而言),可以被應用在檢查 檔案完整性 以及 數字簽名 等場景。

java.security.MessageDigest.getInstance("SHA1").digest(content);
           

2.4 HMAC算法

HMAC 發送方 和 接收方 都基于 key ,利用雜湊演算法 (MD5、SHA1 等)計算,來傳輸和儲存消息,這樣,哪怕黑客竊取了消息,但是沒有key,是 無法計算 出正确的 散列值的,這樣就可以 防止資料被篡改。

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

public class EncryptUtil {

    public static String getBase64String(byte[] s) {
        return Base64.getEncoder().encodeToString(s);
    }

    public static byte[] hamcsha1(String data, String key) {
        try {
            SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), "HmacSHA1");
            Mac mac = Mac.getInstance("HmacSHA1");
            mac.init(signingKey);
            return mac.doFinal(data.getBytes());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

           

3. 結論

針對網絡傳輸的url和參數保護可以使用編碼算法,但是針對加密場景,比如資料保密存儲等,千萬别使用普通的編碼算法,一定要使用加密算法,同理,傳輸過程中有安全性要求的,除了加密算法,還需要通過密鑰來進一步保證資料安全性!