DES
數(shù)據(jù)加密標(biāo)準(zhǔn)(英語(yǔ):Data Encryption Standard赔蒲,縮寫(xiě)為 DES)是一種對(duì)稱密鑰加密塊密碼算法弯淘,1976年被美國(guó)聯(lián)邦政府的國(guó)家標(biāo)準(zhǔn)局確定為聯(lián)邦資料處理標(biāo)準(zhǔn)(FIPS)循衰,隨后在國(guó)際上廣泛流傳開(kāi)來(lái)意狠。它基于使用56位密鑰的對(duì)稱算法乡恕。這個(gè)算法因?yàn)榘恍C(jī)密設(shè)計(jì)元素嘶卧,相對(duì)短的密鑰長(zhǎng)度以及懷疑內(nèi)含美國(guó)國(guó)家安全局(NSA)的后門(mén)而在開(kāi)始時(shí)有爭(zhēng)議童本,DES因此受到了強(qiáng)烈的學(xué)院派式的審查,并以此推動(dòng)了現(xiàn)代的塊密碼及其密碼分析的發(fā)展脸候。
DES現(xiàn)在已經(jīng)不是一種安全的加密方法穷娱,主要因?yàn)樗褂玫?6位密鑰過(guò)短。1999年1月运沦,distributed.net與電子前哨基金會(huì)合作泵额,在22小時(shí)15分鐘內(nèi)即公開(kāi)破解了一個(gè)DES密鑰。也有一些分析報(bào)告提出了該算法的理論上的弱點(diǎn)携添,雖然在實(shí)際中難以應(yīng)用嫁盲。為了提供實(shí)用所需的安全性,可以使用DES的派生算法3DES來(lái)進(jìn)行加密烈掠,雖然3DES也存在理論上的攻擊方法羞秤。在2001年,DES作為一個(gè)標(biāo)準(zhǔn)已經(jīng)被高級(jí)加密標(biāo)準(zhǔn)(AES)所替換左敌。另外瘾蛋,DES已經(jīng)不再作為國(guó)家標(biāo)準(zhǔn)科技協(xié)會(huì)(前國(guó)家標(biāo)準(zhǔn)局)的一個(gè)標(biāo)準(zhǔn)。
在某些文獻(xiàn)中矫限,作為算法的DES被稱為DEA(Data Encryption Algorithm哺哼,數(shù)據(jù)加密算法)佩抹,以與作為標(biāo)準(zhǔn)的DES區(qū)分開(kāi)來(lái)。在發(fā)音時(shí)取董,DES可以作為縮寫(xiě)按字母拼出來(lái)(/?di??i???s/)棍苹,或作為一個(gè)詞念成/?d?z/。
DES算法的入口參數(shù)有三個(gè):Key茵汰、Data枢里、Mode。其中Key為7個(gè)字節(jié)共56位,是DES算法的工作密鑰;Data為8個(gè)字節(jié)64位,是要被加密或被解密的數(shù)據(jù);Mode為DES的工作方式,有兩種:加密或解密蹂午。
3DES
密碼學(xué)中坡垫,三重?cái)?shù)據(jù)加密算法(英語(yǔ):Triple Data Encryption Algorithm,縮寫(xiě)為T(mén)DEA画侣,Triple DEA)冰悠,或稱3DES(Triple DES),是一種對(duì)稱密鑰加密塊密碼配乱,相當(dāng)于是對(duì)每個(gè)數(shù)據(jù)塊應(yīng)用三次數(shù)據(jù)加密標(biāo)準(zhǔn)(DES)算法溉卓。由于計(jì)算機(jī)運(yùn)算能力的增強(qiáng),原版DES密碼的密鑰長(zhǎng)度變得容易被暴力破解搬泥;3DES即是設(shè)計(jì)用來(lái)提供一種相對(duì)簡(jiǎn)單的方法桑寨,即通過(guò)增加DES的密鑰長(zhǎng)度來(lái)避免類(lèi)似的攻擊,而不是設(shè)計(jì)一種全新的塊密碼算法忿檩。
DES有兩種加密運(yùn)算模式
- CBC
需要初始化向量IV尉尾,來(lái)加密第一塊C0.
有點(diǎn)就是比ECB好
缺點(diǎn)不利于并行計(jì)算、誤差會(huì)迭代燥透,還需要初始向量 - ECB
優(yōu)點(diǎn)就是簡(jiǎn)單沙咏,可以并行計(jì)算,不會(huì)迭代誤差
缺點(diǎn)就是隱藏不了模式
填充模式
- ZeroBytePadding
所有需要填充的地方都以0填充班套。 - PKCS7Padding java默認(rèn)沒(méi)有該填充方法
填充的內(nèi)容是需要填充的字節(jié)數(shù)肢藐。如果最后一個(gè)數(shù)據(jù)塊長(zhǎng)度為len,每個(gè)塊的長(zhǎng)度為k吱韭,則要填充的內(nèi)容為:
01 -- if lth mod k = k-1
02 -- if lth mod k = k-2
k k ..k k -- if lth mod k = 0
需要注意的是吆豹,如果最后一個(gè)數(shù)據(jù)塊的長(zhǎng)度len恰好等于k,則需要在后面再添加一個(gè)完整的padding塊理盆,kk...kk痘煤。下面的例子是每8byte為一塊,最后一塊有8byte猿规,需要填充8byte的\x08衷快。
... | DD DD DD DD DD DD DD DD | DD DD DD DD DD DD DD DD | 08 08 08 08 08 08 08 08 | - PKCS5Padding
PKCS5 和 PKCS7 的唯一區(qū)別是PKCS5只能用來(lái)填充64bit的數(shù)據(jù)塊,除此之外可以混用坎拐。 - NoPadding
不填充烦磁,如果加密內(nèi)容不是8字節(jié)整數(shù)倍加密則會(huì)報(bào)錯(cuò) - SSL3Padding
C#的默認(rèn)模式為CBC,默認(rèn)填充方式為PKCS7
java的默認(rèn)模式為ECB养匈,默認(rèn)填充方式為PKCS5Padding
C#中key的size為16和24均可
java中要求key的size必須為24
對(duì)于CBC模式下的向量iv的size兩者均要求必須為8
java平臺(tái)每種加密方式所需密碼長(zhǎng)度
AES/CBC/NoPadding (128)
AES/CBC/PKCS5Padding (128)
AES/ECB/NoPadding (128)
AES/ECB/PKCS5Padding (128)
DES/CBC/NoPadding (56)
DES/CBC/PKCS5Padding (56)
DES/ECB/NoPadding (56)
DES/ECB/PKCS5Padding (56)
DESede/CBC/NoPadding (168)
DESede/CBC/PKCS5Padding (168)
DESede/ECB/NoPadding (168)
DESede/ECB/PKCS5Padding (168)
RSA/ECB/PKCS1Padding (1024, 2048)
RSA/ECB/OAEPWithSHA-1AndMGF1Padding (1024, 2048)
RSA/ECB/OAEPWithSHA-256AndMGF1Padding (1024, 2048)
import android.util.Log;
import java.io.UnsupportedEncodingException;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
/**
* 3DES加密解密
* key長(zhǎng)度為24個(gè)字符哼勇,不足可補(bǔ)零
* IV向量必須為8位<br/>
* 使用Base64.encodeToString(byte[], Base64.NO_WRAP);來(lái)將加密后的byte[]轉(zhuǎn)為String<br/>
* 使用Base64.decode(String, Base64.NO_WRAP);將轉(zhuǎn)為String的加密字符轉(zhuǎn)換為byte[]<br/>
* new String(byte[])將解密后的byte[]轉(zhuǎn)為String<br/>
*/
public class DES3Util {
private static final String TAG = "DES3Util";
private static final String DES3 = "DESede";
///////////////////////////////////////////////////////////////////////////
// DES3
///////////////////////////////////////////////////////////////////////////
/**
* 3DES ECB模式加密
*/
public static byte[] des3EncodeECB(byte[] key, byte[] data) {
try {
SecretKey DESKey = new SecretKeySpec(key, DES3); //生成密鑰
Cipher cipher = Cipher.getInstance(DES3 + "/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, DESKey);
return cipher.doFinal(data);
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, e.getMessage());
return null;
}
}
/**
* 3DES ECB模式解密
*/
public static byte[] des3DecodeECB(byte[] key, byte[] data) {
try {
SecretKey DESKey = new SecretKeySpec(key, DES3); //生成密鑰
Cipher cipher = Cipher.getInstance(DES3 + "/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, DESKey);
return cipher.doFinal(data);
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, e.getMessage());
return null;
}
}
/**
* 3DES CBC模式加密
*/
public static byte[] des3EncodeCBC(byte[] key, byte[] iv, byte[] data) {
try {
SecretKey DESKey = new SecretKeySpec(key, DES3); //生成密鑰
Cipher cipher = Cipher.getInstance(DES3 + "/CBC/PKCS5Padding");
IvParameterSpec ips = new IvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE, DESKey, ips);
return cipher.doFinal(data);
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, e.getMessage());
return null;
}
}
/**
* 3DES CBC模式加密
*/
public static byte[] des3DecodeCBC(byte[] key, byte[] iv, byte[] data) {
try {
SecretKey DESKey = new SecretKeySpec(key, DES3); //生成密鑰
Cipher cipher = Cipher.getInstance(DES3 + "/CBC/PKCS5Padding");
IvParameterSpec ips = new IvParameterSpec(iv);
cipher.init(Cipher.DECRYPT_MODE, DESKey, ips);
return cipher.doFinal(data);
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, e.getMessage());
return null;
}
}
/**
* 根據(jù)字符串生成密鑰字節(jié)數(shù)組
*
* @param keyStr 密鑰字符串
*/
private static byte[] build3DesKey(String keyStr) {
try {
byte[] key = new byte[24]; //聲明一個(gè)24位的字節(jié)數(shù)組都伪,默認(rèn)里面都是0
byte[] temp = keyStr.getBytes("UTF-8"); //將字符串轉(zhuǎn)成字節(jié)數(shù)組
if (key.length > temp.length) {
//如果temp不夠24位,則拷貝temp數(shù)組整個(gè)長(zhǎng)度的內(nèi)容到key數(shù)組中
System.arraycopy(temp, 0, key, 0, temp.length);
} else {
//如果temp大于24位积担,則拷貝temp數(shù)組24個(gè)長(zhǎng)度的內(nèi)容到key數(shù)組中
System.arraycopy(temp, 0, key, 0, key.length);
}
return key;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
Log.e(TAG, e.getMessage());
return null;
}
}
}