無(wú)可厚非午乓,信息安全是互聯(lián)網(wǎng)技術(shù)中非常重要的一塊,所以覺得有必要系統(tǒng)學(xué)習(xí)一下幾種java的加密方法闸准。
一益愈、DES
DES是一種對(duì)稱密碼算法,解密不是加密的逆序夷家,而是使用同樣的加密步驟蒸其,使用次序相反加密密鑰。如果各輪加密密鑰分別是K1库快,K2摸袁,K3…K16,那么解密密鑰就是K16义屏,K15靠汁,K14…K1蜂大。但是大多數(shù)情況下加解密都是使用同一個(gè)密鑰,密鑰的安全也是非常重要的蝶怔,(可以將DES算法包括整個(gè)類和加密密鑰等生成.so文件來(lái)引用)奶浦。
1. DES算法的安全性和發(fā)展
DES的安全性首先取決于密鑰的長(zhǎng)度。密鑰越長(zhǎng)踢星,破譯者利用窮舉法搜索密鑰的難度就越大澳叉。目前,根據(jù)當(dāng)今計(jì)算機(jī)的處理速度和能力斩狱,56位長(zhǎng)度的密鑰已經(jīng)能夠被破解耳高,而128位的密鑰則被認(rèn)為是安全的,但隨著時(shí)間的推移所踊,這個(gè)數(shù)字也遲早會(huì)被突破。
2.常見錯(cuò)誤
報(bào)錯(cuò)如下:
javax.crypto.IllegalBlockSizeException: Input length must be multiple of 8 when decrypting with padded cipher
原因和處理:我的原因是 mEncryptCipher.init(Cipher.ENCRYPT_MODE,getKey(KEY.getBytes()))中
的Cipher.ENCRYPT_MODE寫成了Cipher.DECRYPT_MODE這種低級(jí)錯(cuò)誤概荷;
2. 代碼實(shí)現(xiàn)
加密:
/**
* Created by ljt on 2017/6/15.
*/
public class DesUtil {
/** 對(duì)稱加解密DES密鑰Key*/
public final static String KEY = "ItisImpor";
private static Cipher mEncryptCipher = null;
private static Cipher mDecryptCipher = null;
public DesUtil() throws Exception {
//初始化加密和解密密碼提供類
mEncryptCipher = Cipher.getInstance("DES");
mEncryptCipher.init(Cipher.ENCRYPT_MODE,getKey(KEY.getBytes()));
mDecryptCipher = Cipher.getInstance("DES");
mDecryptCipher.init(Cipher.DECRYPT_MODE,getKey(KEY.getBytes()));
}
// ****** 加密 ******
/**
* 對(duì) 字符串 加密
* */
public String encrypt(String strIn) throws Exception {
return byte2HexStr(encrypt(strIn.getBytes()));
}
/**
* 對(duì) 字節(jié)數(shù)組 加密
*/
public byte[] encrypt(byte[] arrB) throws Exception {
return mEncryptCipher.doFinal(arrB);
}
// ****** 解密 ******
/**
* 解密 字符串
* */
public String decrypt(String strIn) throws Exception {
return new String(decrypt(hexStr2Byte(strIn)));
}
/**
* 解密 字節(jié)數(shù)組
*/
public byte[] decrypt(byte[] arrB) throws Exception {
return mDecryptCipher.doFinal(arrB);
}
/**
* 解密用的密鑰(字節(jié)數(shù)組)長(zhǎng)度必須為8個(gè)字節(jié)否則返回null, 不足8位時(shí)后面補(bǔ)0秕岛,超出8位只取前8位
*
* @param arrBTmp 構(gòu)成該字符串的字節(jié)數(shù)組
* @return 生成的密鑰
* @throws Exception
*/
private Key getKey(byte[] arrBTmp) throws Exception {
// 創(chuàng)建一個(gè)空的8位字節(jié)數(shù)組(默認(rèn)值為0)
byte[] arrB = new byte[8];
// 將原始字節(jié)數(shù)組轉(zhuǎn)換為8位
for (int i = 0; i < arrBTmp.length && i < arrB.length; i++) {
arrB[i] = arrBTmp[i];
}
// 生成密鑰
Key key = new javax.crypto.spec.SecretKeySpec(arrB, "DES");
return key;
}
/**
* HEX轉(zhuǎn)碼 String to Byte
*/
public static byte[] hexStr2Byte(String strIn) throws Exception {
byte[] arrB = strIn.getBytes();
int iLen = arrB.length;
// 兩個(gè)字符表示一個(gè)字節(jié),所以字節(jié)數(shù)組長(zhǎng)度是字符串長(zhǎng)度除以2
byte[] arrOut = new byte[iLen / 2];
for (int i = 0; i < iLen; i = i + 2) {
String strTmp = new String(arrB, i, 2);
arrOut[i / 2] = (byte) Integer.parseInt(strTmp, 16);
}
return arrOut;
}
/**
* HEX轉(zhuǎn)碼 Byte to String
*/
public static String byte2HexStr(byte[] arrB) throws Exception {
int iLen = arrB.length;
// 每個(gè)byte用兩個(gè)字符才能表示误证,所以字符串的長(zhǎng)度是數(shù)組長(zhǎng)度的兩倍
StringBuffer sb = new StringBuffer(iLen * 2);
for (int i = 0; i < iLen; i++) {
int intTmp = arrB[i];
// 把負(fù)數(shù)轉(zhuǎn)換為正數(shù)
while (intTmp < 0) {
intTmp = intTmp + 256;
}
// 小于0F的數(shù)需要在前面補(bǔ)0
if (intTmp < 16) {
sb.append("0");
}
sb.append(Integer.toString(intTmp, 16));
}
return sb.toString();
}
public static void main(String[] args) {
try {
System.out.println("加密前:");
DesUtil des = new DesUtil();
String pwd = des.encrypt("12345uvwxwz");
System.out.println("加密后:" + pwd);
pwd = des.decrypt(pwd);
System.out.println("解密密后:" + pwd);
} catch (Exception e) {
e.printStackTrace();
}
}
}
修改幾遍Key值可以發(fā)現(xiàn):
1继薛、key中只有8個(gè)字節(jié)有用,如果使用前面8個(gè)愈捅,則第8個(gè)字節(jié)后面的字符不影響加密解密遏考;