本文介紹了3DES加密特性,加密特點,3DES是對稱加密悔常,用一個密鑰對內(nèi)容進行加密怀吻,必須使用相同的密鑰進行解密, 密鑰必須配置瞬浓,而且長度為24位,不足24位蓬坡,用0位進行補全猿棉,本文也順帶介紹了其它加密算法磅叛,最后使用java語句實現(xiàn)了3DES加解密
眾多的加密手段大致可以分為單項加密和雙向加密。單項加密指通過對數(shù)據(jù)進行摘要計算生成密文萨赁,密文不可逆推還原弊琴,比如有MD5、SHA等杖爽;雙向加密則相反敲董,指可以把密文逆推還原成明文,其中雙向加密又分為對稱加密和非對稱加密慰安。對稱加密是指數(shù)據(jù)使用者必須擁有同樣的密鑰才可以進行加密解密腋寨,就像大家共同約定了一組暗號一樣,對稱加密的手段有DES化焕、3DES精置、AES、IDEA锣杂、RC4、RC5等番宁;而非對稱加密相對于對稱加密而言元莫,無需擁有同一組密鑰,它是一種“信息公開的密鑰交換協(xié)議”蝶押。非對稱加密需要公開密鑰和私有密鑰兩組密鑰踱蠢,公開密鑰和私有密鑰是配對起來的,也就是說使用公開密鑰進行數(shù)據(jù)加密棋电,只有對應的私有密鑰才能進行解密茎截。此類的加密手段有RSA、DSA等赶盔。
初識3DES
3DES企锌,中文名“三重數(shù)據(jù)加密算法”, 也稱為3DESede或TripleDES,是三重數(shù)據(jù)加密于未,且可以逆推的一種算法方案撕攒。
1975年美國IBM公司成功研究并發(fā)布了DES加密算法,但DES密碼長度容易被暴力破解烘浦,通過對DES算法進行改進抖坪,針對每個數(shù)據(jù)塊進行 三次DES加密须喂,也就是3DES加密算法家夺。
但由于3DES的算法是公開的,所以算法本身沒什么秘密可言槽驶,主要依靠唯一密鑰來確保數(shù)據(jù)加密解密的安全握侧。
有人可能會問蚯瞧,那3DES到底安不安全呢嘿期?!目前為止状知,還沒有人能破解3DES秽五,所以你要是能破解它,都足以震驚整個信息安全界了……
原理
使用 3 條 56 位的密鑰對數(shù)據(jù)進行三次加密饥悴。3DES(即 Triple DES)是 DES 向 AES 過渡的加密算法(NIST 將 3-DES 指定為過渡的加密標準)坦喘。
其具體實現(xiàn)如下:設 Ek() 和 Dk() 代表 DES 算法的加密和解密過程,K 代表 DES 算法使用的密鑰西设,P 代表明文瓣铣,C 代表密文,這樣:
3DES 加密過程為:C = Ek3 ( Dk2 ( Ek1 ( P ) ) )
3DES 解密過程為:P = Dk1 ( EK2 ( Dk3 ( C ) ) )
Java使用3DES加密解密的流程
①傳入共同約定的密鑰(keyBytes)以及算法(Algorithm)贷揽,來構(gòu)建SecretKey密鑰對象
SecretKey deskey = new SecretKeySpec(keyBytes, Algorithm); keyBytes必須是24字節(jié)
②根據(jù)算法實例化Cipher對象棠笑。它負責加密/解密
Cipher c1 = Cipher.getInstance(Algorithm);
③傳入加密/解密模式以及SecretKey密鑰對象,實例化Cipher對象
c1.init(Cipher.ENCRYPT_MODE, deskey);
④傳入字節(jié)數(shù)組禽绪,調(diào)用Cipher.doFinal()方法蓖救,實現(xiàn)加密/解密,并返回一個byte字節(jié)數(shù)組
c1.doFinal(src);
24位解密串(必須是24位)
3DES的密鑰必須是24位的byte數(shù)組
隨便拿一個String.getBytes()是不行的印屁,會報如下錯誤
java.security.InvalidKeyException: Invalid key length: 59 bytes
解決方法有很多
①按密鑰固定長度重新定義字符串循捺;
②先把字符串用Base64或者MD5加密,然后截取固定長度的字符轉(zhuǎn)成byte數(shù)組雄人;
③字符串轉(zhuǎn)成Byte數(shù)組从橘,針對該數(shù)組進行修改,若長度過長則只截取一部分础钠,若長度不夠則補零
JAVA代碼實現(xiàn)
/**
SecretUtils {3DES加密解密的工具類 }
@author William
-
@date 2013-04-19
*/
public class SecretUtils {//定義加密算法恰力,有DES、DESede(即3DES)旗吁、Blowfish
private static final String Algorithm = "DESede";
private static final String PASSWORD_CRYPT_KEY = "2012PinganVitality075522628888ForShenZhenBelter075561869839";
/**
* 加密方法
* @param src 源數(shù)據(jù)的字節(jié)數(shù)組
* @return
*/
public static byte[] encryptMode(byte[] src) {
try {
SecretKey deskey = new SecretKeySpec(build3DesKey(PASSWORD_CRYPT_KEY), Algorithm); //生成密鑰
Cipher c1 = Cipher.getInstance(Algorithm); //實例化負責加密/解密的Cipher工具類
c1.init(Cipher.ENCRYPT_MODE, deskey); //初始化為加密模式
return c1.doFinal(src);
} catch (java.security.NoSuchAlgorithmException e1) {
e1.printStackTrace();
} catch (javax.crypto.NoSuchPaddingException e2) {
e2.printStackTrace();
} catch (java.lang.Exception e3) {
e3.printStackTrace();
}
return null;
}
/**
* 解密函數(shù)
* @param src 密文的字節(jié)數(shù)組
* @return
*/
public static byte[] decryptMode(byte[] src) {
try {
SecretKey deskey = new SecretKeySpec(build3DesKey(PASSWORD_CRYPT_KEY), Algorithm);
Cipher c1 = Cipher.getInstance(Algorithm);
c1.init(Cipher.DECRYPT_MODE, deskey); //初始化為解密模式
return c1.doFinal(src);
} catch (java.security.NoSuchAlgorithmException e1) {
e1.printStackTrace();
} catch (javax.crypto.NoSuchPaddingException e2) {
e2.printStackTrace();
} catch (java.lang.Exception e3) {
e3.printStackTrace();
}
return null;
}
/*
* 根據(jù)字符串生成密鑰字節(jié)數(shù)組
* @param keyStr 密鑰字符串
* @return
* @throws UnsupportedEncodingException
*/
public static byte[] build3DesKey(String keyStr) throws UnsupportedEncodingException{
byte[] key = new byte[24]; //聲明一個24位的字節(jié)數(shù)組踩萎,默認里面都是0
byte[] temp = keyStr.getBytes("UTF-8"); //將字符串轉(zhuǎn)成字節(jié)數(shù)組
/*
* 執(zhí)行數(shù)組拷貝
* System.arraycopy(源數(shù)組,從源數(shù)組哪里開始拷貝很钓,目標數(shù)組驻民,拷貝多少位)
*/
if(key.length > temp.length){
//如果temp不夠24位,則拷貝temp數(shù)組整個長度的內(nèi)容到key數(shù)組中
System.arraycopy(temp, 0, key, 0, temp.length);
}else{
//如果temp大于24位履怯,則拷貝temp數(shù)組24個長度的內(nèi)容到key數(shù)組中
System.arraycopy(temp, 0, key, 0, key.length);
}
return key;
}
}
測試代碼
public class Main {
/**
* @param args
*/
public static void main(String[] args) {
String msg = "3DES加密解密案例";
System.out.println("【加密前】:" + msg);
//加密
byte[] secretArr = SecretUtils.encryptMode(msg.getBytes());
System.out.println("【加密后】:" + new String(secretArr));
//解密
byte[] myMsgArr = SecretUtils.decryptMode(secretArr);
System.out.println("【解密后】:" + new String(myMsgArr));
}
}
參考資料
3DES在線測試工具:http://www.seacha.com/tools/3des.php
本文demo下載:http://www.wisdomdd.cn/Wisdom/resource/articleDetail.htm?resourceId=300
?
JAVA代碼實現(xiàn)