今天在网上搜了一下DES加密算法(注释部分展开),总报如下错误:
javax.crypto.IllegalBlockSizeException: Input length must be multiple of 8 when decrypting with padded cipher
最终原因是byte数组是不能强制转换成字符串的,换言之:字符串(2个字节)和byte数组在这种情况下不是互逆的;要避免这种情况,我们需要做一些修订,可以考虑将二进制数据转换成十六进制表示
在网上找了些代码,修改以后如下:
public class DES {
private Key key; //密钥
/**
* 根据参数生成KEY
*
* @param strKey 密钥字符串
*/
public void getKey(String strKey) {
try {
KeyGenerator _generator = KeyGenerator.getInstance("DES");
_generator.init(new SecureRandom(strKey.getBytes()));
this.key = _generator.generateKey();
_generator = null;
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 加密String明文输入,String密文输出
*
* @param strMing String明文
* @return String密文
*/
public String getEncString(String strMing) {
byte[] byteMi = null;
byte[] byteMing = null;
String strMi = "";
try {
/*byteMing = strMing.getBytes("UTF8");
byteMi = this.getEncCode(byteMing);
strMi = new String(byteMi, "UTF8");*/
strMi = parseByte2HexStr(getEncCode(strMing.getBytes()));
} catch (Exception e) {
e.printStackTrace();
} finally {
byteMing = null;
byteMi = null;
}
return strMi;
}
/**
* 解密 以String密文输入,String明文输出
*
* @param strMi String密文
* @return String明文
*/
public String getDesString(String strMi) {
byte[] byteMi = null;
byte[] byteMing = null;
String strMing = "";
try {
/*byteMi = strMi.getBytes("UTF8");
byteMing = this.getDesCode(byteMi);
strMing = new String(byteMing, "UTF8");*/
strMing = new String(getDesCode(parseHexStr2Byte(strMi)));
} catch (Exception e) {
e.printStackTrace();
} finally {
byteMing = null;
byteMi = null;
}
return strMing;
}
/**
* 加密以byte[]明文输入,byte[]密文输出
*
* @param byteS byte[]明文
* @return byte[]密文
*/
private byte[] getEncCode(byte[] byteS) {
byte[] byteFina = null;
Cipher cipher;
try {
cipher = Cipher.getInstance("DES");
cipher.init(Cipher.ENCRYPT_MODE, key);
byteFina = cipher.doFinal(byteS);
} catch (Exception e) {
e.printStackTrace();
} finally {
cipher = null;
}
return byteFina;
}
/**
* 解密以byte[]密文输入,以byte[]明文输出
*
* @param byteD byte[]密文
* @return byte[]明文
*/
private byte[] getDesCode(byte[] byteD) {
Cipher cipher;
byte[] byteFina = null;
try {
cipher = Cipher.getInstance("DES");
cipher.init(Cipher.DECRYPT_MODE, key);
byteFina = cipher.doFinal(byteD);
} catch (Exception e) {
e.printStackTrace();
} finally {
cipher = null;
}
return byteFina;
}
/**
* 将二进制转换成16进制
* @param buf
* @return
*/
public String parseByte2HexStr(byte buf[]) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < buf.length; i++) {
String hex = Integer.toHexString(buf[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
sb.append(hex.toUpperCase());
}
return sb.toString();
}
/**
* 将16进制转换为二进制
* @param hexStr
* @return
*/
public byte[] parseHexStr2Byte(String hexStr) {
if (hexStr.length() < 1)
return null;
byte[] result = new byte[hexStr.length() / 2];
for (int i = 0; i < hexStr.length() / 2; i++) {
int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2),
16);
result[i] = (byte) (high * 16 + low);
}
return result;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
DES encrypt = new DES();
encrypt.getKey("嘿嘿");
String strEnc = encrypt.getEncString("hi,我是程序员");
System.out.println(strEnc);
String strDes = encrypt.getDesString(strEnc);
System.out.println(strDes);
}
}