java安全之加密技術
加密方式
主要有:對稱加密演算法,基礎加密演算法,非對稱加密演算法。
一,對稱加密演算法
只有一個金鑰key進行加密解密,可以逆向加解密。
1.凱撒密碼
古代有名的加密演算法,將加密的資料進行一定的以為,屬於對稱加密,金鑰key = 2(int 值)。
這種加密非常簡單,只需要對相應的明文移位就得到了加密後的密文,如:明文為abc,key = 2(移2位),那麼密文為cde,原理非常的簡單。 這種加密在後來明顯不能滿足時代發展的需要,通過**頻度分析法**,可以快速的破解。 頻度分析法:這種方法通過一定的理論和相關統計,得到一定的規律就是:字母e出現的概率最高,t,a,o,n,i,r,s和是常用頻率的字母,通過頻度分析和逆向凱撒密碼,就可以得到破譯的幾種明文。
2.DES
速度較快,適用於加密大量資料的場合。
DES金鑰至少8個數字(64個位元位),使用了前56個位元位,後8位用作校驗碼,超過8對密文沒有影響。
3.DES
基於DES,強度更高,但是加密效率不高。
對一塊資料用3個不同的金鑰進行3次加密
DES演算法有四種工作模式:
1.ECB:電子密碼本模式
優點:
1.有利於平行計算;
2.誤差不會被傳送;
缺點:
1.不能隱藏明文的模式;
2.可能對明文進行主動攻擊。
2.CBC:加密分組連結模式
密文呈分組連結的特點,密文之間有依賴關係,加密強度更高,能防止主動攻擊。
3.CFB:加密反饋模式
隱藏了明文模式;
4.OFB:輸出反饋模式
5.CTR模式
實現程式碼
public class DESUtil {
//演算法名稱
public static final String KEY_ALGORITHM = "DES";
//演算法名稱/加密模式/填充方式
public static final String CIPHER_ALGORITHM = "DES/ECB/NoPadding";
/**
* 生成金鑰key物件
* @param KeyStr 金鑰字串
* @return 金鑰物件
* @throws Exception
*/
private static SecretKey keyGenerator(String keyStr) throws Exception {
byte input[] = HexString2Bytes(keyStr);
DESKeySpec desKey = new DESKeySpec(input);
//建立一個密匙工廠,然後用它把DESKeySpec轉換成
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey securekey = keyFactory.generateSecret(desKey);
return securekey;
}
/**
* 加密資料
* @param data 待加密資料
* @param key 金鑰
* @return 加密後的資料
*/
public static String encrypt(String data, String key) throws Exception {
Key deskey = keyGenerator(key);
// 例項化Cipher物件,它用於完成實際的加密操作
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
SecureRandom random = new SecureRandom();
// 初始化Cipher物件,設定為加密模式
cipher.init(Cipher.ENCRYPT_MODE, deskey, random);
byte[] results = cipher.doFinal(data.getBytes());
for (int i = 0; i < results.length; i++) {
System.out.print(results[i] + " ");
}
System.out.println();
// 執行加密操作。加密後的結果通常都會用Base64編碼進行傳輸
return Base64.encodeBase64String(results);
}
/**
* 解密資料
* @param data 待解密資料
* @param key 金鑰
* @return 解密後的資料
*/
public static String decrypt(String data, String key) throws Exception {
Key deskey = keyGenerator(key);
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
//初始化Cipher物件,設定為解密模式
cipher.init(Cipher.DECRYPT_MODE, deskey);
// 執行解密操作
return new String(cipher.doFinal(Base64.decodeBase64(data)));
}
4.AES
加密強度升級,金鑰為128(只能為128)個位元。
高階加密標準,是下一代加密演算法標準, 速度快,安全級別高
程式碼實現參考DES,兩者實現差不多。
二,基本的單向加密演算法
基本的單向加密演算法有以下幾種:
BASE64 嚴格地說,屬於編碼格式,而非加密演算法
MD5(Message Digest algorithm 5,資訊摘要演算法)
SHA(Secure Hash Algorithm,安全雜湊演算法)
HMAC(Hash Message Authentication Code,雜湊訊息鑑別碼)
1.BASE64
Base64編碼可用於在HTTP,mime協議下快速傳輸資料, 嚴格地說,屬於編碼格式,而非加密演算法。
Base64的作用:將非ASCII字元的資料轉換成ASCII字元的一種方法,因為某些系統中只能使用ASCII字元(比如傳輸郵件只能傳輸ASCII)。
實現
public class BASE64 {
// 主要使用到兩個類,BASE64Decoder,BASE64Encoder
// BASE64解密
public static byte[] decryptBASE64(String key) throws Exception {
return (new BASE64Decoder()).decodeBuffer(key);
}
// BASE64加密
public static String encryptBASE64(byte[] key) throws Exception {
return (new BASE64Encoder()).encodeBuffer(key);
}
}
2.MD5
資訊摘要演算法,用於確保資訊傳輸完整一致。廣泛用於加密和解密技術,常用於檔案校驗。不管檔案多大,經過MD5後都能生成唯一的MD5值(SHA-1與此類似)
特點
1、任意長度的資料,MD5值長度都是固定的。
2、對原資料進行任何改動,哪怕只修改1個位元組,所得到的MD5值都有很大區別。
3、弱抗碰撞:已知原資料和其MD5值,想找到一個具有相同MD5值的資料(即偽造資料)是非常困難的。
4、強抗碰撞:想找到兩個不同的資料,使它們具有相同的MD5值,是非常困難的。
以下幾行程式碼可以實現實現
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] inputData = inputStr.getBytes();
md.update(inputData);
bigInteger = new BigInteger(md.digest());
SHA
Secure Hash Algorith,安全雜湊演算法,是數字簽名等密碼學應用中重要的工具,被廣泛地應用於電子商務等資訊保安領域,較MD5更為安全。
SHA1比MD5安全,是因為SHA-1摘要為160位,MD5摘要為128位,相差32位,因此SHA1的強度更大。
程式碼實現
public static byte[] encrypt(byte[] data) throws Exception {
MessageDigest sha = MessageDigest.getInstance(KEY_SHA);
sha.update(data);
return sha.digest();
}
三,非對稱加密演算法
存在公鑰和私鑰的概念,要完成加解密操作,需要兩個金鑰同時參與。公鑰加密的資料必須使用私鑰才可以解密,同樣,私鑰加密的資料也 只能通過公鑰進行解密。
RSA加密演算法
RSA加密演算法是一種典型的非對稱加密演算法。
原理
它的原理非常簡單,如下圖:
產生的問題1
從上面的傳輸過程我們可以看出,公鑰是直接傳輸給B,那麼它可能被截獲,A向B的加密資料就可能用公鑰進行解密,造成資料洩露。
建立更加安全的傳輸通道
建立更加安全的加密通道,在A,B兩端分別產生金鑰對,分別將各自的公鑰暴露給對方,如下圖:
產生的問題2
這種安全通道,相對來說已經很堅固,但是這種方式也可能存在資料傳遞被模擬的隱患,需要通過數字簽名進一步提升安全性。
數字簽名以及數字證書
(1)資訊 + HASH = 摘要 摘要 + 私鑰 = 數字簽名(給收方做對比用的,驗證收發內容是否一致)
(2)公鑰 + 相關資訊 + CA私鑰 = 數字證書(驗證傳送者是否正確,是可信任的公鑰)
A的公鑰必須是證書中心頒發的,不然就需要對A做公鑰認證(參考這篇博文):
注意:
如果A的公鑰被替換掉,B端就不能確認公鑰是否是A端的公鑰,這時B可以讓A可以去找"證書中心"(certificate authority,簡稱CA),為公鑰做認證,證書中心用自己的私鑰,對A的公鑰和一些相關資訊一起加密,生成"數字證書"(Digital Certificate),傳送資訊給B在簽名的同時附上數字證書就可以了。B收信後,用CA的公鑰解開數字證書,就可以拿到A真實的公鑰了,然後就能證明"數字簽名"是否真的是A籤的。
四,加密演算法的選擇
對於對稱解密演算法和非對稱加密演算法,在實際使用的過程中該使用哪一種?
使用建議:
1.由於非對稱加密演算法的執行速度比對稱加密演算法的速度慢很多,當我們需要加密大量的資料時,建議採用對稱加密演算法,提高加解密速度。當資料量很小時,我們可以考慮採用非對稱加密演算法(對稱加密的金鑰管理也比較複雜)。
2.對稱加密演算法不能實現簽名,因此簽名只能非對稱演算法。
實際使用
實際應用中,兩者混合使用
採用非對稱加密演算法管理對稱演算法的金鑰,然後用對稱加密演算法加密資料,這樣我們就集成了兩類加密演算法的優點,既實現了加密速度快的優點,又實現了安全方便管理金鑰的優點。