常見加密解密和URL編解碼
Base64
概念:
基於64個可打印字符,用於表示二進制數據,使用的字符包括大小寫拉丁字母各26個、數字10個、加號+和斜槓/,共64個字符,等號=用來作爲後綴用途
2^6=64 因此一個可打印字符由6bit來表示
3個字符(38)可由4個可打印字符表示(46)
作用:
常用於用來表示二進制數據
MD5 (Message Digest algorithm 5)
概念:
一種摘要算法,非對稱加密,不可逆(因爲會將原文部分信息丟失),長度固定(128位) 16進製表示
哈希算法的一種
作用:
不用來做安全性加密,因爲可以被碰撞出來 常用來進行文件校驗 防止文件被篡改或替換
碰撞: 不同的原數據可能得到相同的哈希值 此爲碰撞 而若校驗該哈希值,則可能被碰撞得到而導致不安全
彩虹表: 對一些常見的數值(如123456)MD5得到的值保存到一個巨大的表中,便於拿到哈希值進行反查原數據
密鑰salt 在加密算法中主要被設計用來防止“字典攻擊”。字典攻擊也是一種窮舉的暴力破解法。字典中會假設一定數量的密碼值,攻擊者會嘗試用這些密碼來解密密文。Salt是在密鑰導出之前在密碼末尾引入的隨機字節,它使這類攻擊變得非常困難。
初始化向量IV 在加密算法中起到的也是增強破解難度的作用。在加密過程中,如果遇到相同的數據塊,其加密出來的結果也一致,相對就會容易破解。加密算法在加密數據塊的時候,往往會同時使用密碼和上一個數據塊的加密結果。因爲要加密的第一個數據塊顯然不存在上一個數據塊,所以這個初始化向量就是被設計用來當作初始數據塊的加密結果。
數字信封 採用對稱加密算法加密數據,非對稱加密算法加密對稱密鑰的方式解決了以上的問題
SSL
SHA-1 SHA-256
類似MD5 只是比MD5安全 更難被碰撞
SHA-1長度爲160位 SHA-256長度爲256位
對稱加密
使用相同密鑰進行加密和解密
優點:速度快 適用於大數據 大文件
缺點:但需要相同密鑰,密鑰傳輸過程中可能被截獲
一、DES算法
二、AES算法
IV向量:是否考慮方向性 如0000000000000000 不考慮方向
長度: 有128 192 256位 MCRYPT_RIJNDAEL_256
模式:MCRYPT_MODE_ECB(分塊加密) CBC CFB等模式
解密祕鑰:key
填充: 是否末尾填充 NoPadding PKCS5Padding等
kotlin aes解密:
fun decryptAes(inpute: ByteArray): String {
// 創建cipher對象
val cipher = Cipher.getInstance("AES/ECB/NoPadding")
// 初始化cipher
// 通過祕鑰工廠生產祕鑰
val keySpec = SecretKeySpec(key.toByteArray(), "AES")
cipher.init(Cipher.DECRYPT_MODE, keySpec)
// 加密、解密
val encrypt = cipher.doFinal(inpute)
return String(encrypt)
}
非對稱加密
A自己生成公鑰和私鑰 將公鑰給到B B通過公鑰對內容進行加密,然後A通過祕鑰進行加密
優點: 安全 不會暴露私鑰
缺點;速度慢
一、RSA加密
核心:難以將一個數拆分成兩個大的素數(質數)
URLEncode RawURLEncode
英文數字不處理 處理特殊符號(空格、換行、等於) 和 中文字符
兩者唯一區別是對於空格字符的處理
urlencode處理成“+”,rawurlencode處理成“%20”
加密工具類
public class MD5 {
public static String md5(String content) {
byte[] hash;
try {
// MessageDigest.getInstance("MD5") 通過信息摘要單例的構造函數獲取信息摘要對象md5
// content.getBytes("UTF-8") 獲取字符串的字節數組.
// .digest()對字節數組進行摘要,得到摘要字節數組:
hash = MessageDigest.getInstance("MD5").digest(content.getBytes("UTF-8"));
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("NoSuchAlgorithmException",e);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("UnsupportedEncodingException", e);
}
// 把摘要數組中的每一個字節轉換成16進制,並拼在一起就得到了MD5值.
StringBuilder hex = new StringBuilder(hash.length * 2);
for (byte b : hash) {
if ((b & 0xFF) < 0x10){
hex.append("0");
}
hex.append(Integer.toHexString(b & 0xFF));
}
return hex.toString();
}
}