零、 首先明确一下概念(simple what?):
MD5:摘要算法,不可逆
DES:对称加密算法,用密钥可以解密(可逆)
BASE64:编码算法,可逆
一、 Base64(DES(MD5(消息体) + 消息体))加密 (How 原理)
Des加密保证消息的不可阅读性。
对消息的加密算法:Base64(DES(MD5(消息体) + 消息体))
消息采用的DES加密算法规则如下:
1.密钥是一个长度16、由16进制字符组成的字符串,如:1234567890ABCDEF
使用时,相临的两位理解为一个16进制数的明文,然后转换为实际使用的8位密钥
2. 待加密数据按照PKCS5规则进行补位。(缺7位补7个0x07,缺6位则补6个0x06,以次类推,如果正好8位,也需要补8个0x08)
3. 实际加密模式选择DES-ECB
4. 经过DES加密后的数据必须通过Base64编码转换为明文的字符串
二、Base64(DES(MD5(消息体) + 消息体))加密 (How 原理)
请楼主证实一个说法:你说“我有一个密码”,是指加密用的“密钥”?还是指最后得到的“密文”?
如果没有“密钥”,是无法还原出“消息体”的,因为 DES 解密需要“密钥”。
所以,解决解密问题:
1. 用BASE64还原算法得到“DES(MD5(消息体) + 消息体)”
2. 用你手里的密钥进行DES解密,得到“MD5(消息体) + 消息体”
3. 剥掉前面的 16 个字节,得到“消息体”
4. (可选步骤)对“消息体”进行 MD5 计算,得到 16 字节的摘要信息,跟前面剥掉的 16 个字节进行比较,如果一致的话,表示整个过程成功。
三、Java版加密和解密实现: (How 实践/具体如何做)
import java.security.SecureRandom;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.Cipher;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
public class EncryptOrDecrypt {
private static BASE64Decoder base64Decoder = new BASE64Decoder();
private static BASE64Encoder base64Eecoder = new BASE64Encoder();
/*
* 加密
*/
public static String EncryptString(String strText, String sKey) {
// MD5加密
String md5s = EncryptMD5.getMD5(strText);
try {
SecureRandom random = new SecureRandom();
byte[] bkey = getKey(sKey);
DESKeySpec deskey = new DESKeySpec(bkey);
// 创建一个密钥工厂,然后用它把DESKeyspec转换成
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey securekey = keyFactory.generateSecret(deskey);
// cipher对象实际完成加密操作
Cipher cipher = Cipher.getInstance("DES");
// 用密钥初化Cipher对象
cipher.init(Cipher.ENCRYPT_MODE, securekey, random);
// 现在,获取数据并加密
// 正式执行加密操作
String str = md5s + strText;
byte[] t = str.getBytes("UTF-8");
byte[] bResult = cipher.doFinal(t);
// 1、加密完byte[] 后,需要将加密了的byte[] 转换成base64保存,如:
// BASE64Encoder base64encoder = new BASE64Encoder();
// String encode=base64encoder.encode(bytes);
return base64Eecoder.encode(bResult);
} catch (Throwable e) {
e.printStackTrace();
}
return null;
}
/*
* 解密
*/
public static String DecryptString(String strText, String sKey)
throws Exception {
// DES算法要求有一个可信任的随机数源
SecureRandom random = new SecureRandom();
// 创建一个DesKeySpec对象
byte[] bkey = getKey(sKey);
DESKeySpec desKey = new DESKeySpec(bkey);
// 创建一个密钥工厂
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
// 将DESKeySpec对象转换成SecretKey对象
SecretKey secreKey = keyFactory.generateSecret(desKey);
// Cipher对象实际完成解密操作
Cipher cipher = Cipher.getInstance("DES");
// 用密钥初始化Cipher对象
cipher.init(Cipher.DECRYPT_MODE, secreKey, random);
// 真正开始解密
// 2、解密前,需要将加密后的字符串从base64转回来再解密,如:
// BASE64Decoder base64decoder = new BASE64Decoder();
// byte[] encodeByte = base64decoder.decodeBuffer(s);
byte[] encodeByte = base64Decoder.decodeBuffer(strText);
byte[] b = cipher.doFinal(encodeByte);
String s = new String(b);
return s.substring(32);
}
public static byte[] getKey(String key) {
byte[] b = new byte[8];
for (int i = 0; i < 8; i++) {
b[i] = (byte) (0xff & Integer.parseInt(key.substring(i * 2,
i * 2 + 2), 16));
}
return b;
}
}
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/*
* MD5加密
*/
public class EncryptMD5 {
private static MessageDigest msgdig = null;
public static final synchronized String getMD5(String s) {
if (msgdig == null)
try {
msgdig = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
System.err
.println("Failed to load the MD5 MessageDigest. Jive will be unable to function normally.");
e.printStackTrace();
}
msgdig.update(s.getBytes());
return toHex(msgdig.digest());
}
public static final String toHex(byte byteArray[]) {
StringBuffer sb = new StringBuffer(byteArray.length * 2);
for (int i = 0; i < byteArray.length; i++) {
if ((byteArray[i] & 0xff) < 16)
sb.append("0");
sb.append(Long.toString(byteArray[i] & 0xff, 16));
}
return sb.toString();
}
}
四、 参考:
1 Base64(DES(MD5(消息体) + 消息体))解密
2 Java DES+MD5加密和解密 http://hi.baidu.com/redlineren/blog/item/304bd51796d44d07c83d6da2.html
3 Java MD5加密方法 http://hi.baidu.com/redlineren/blog/item/3af945822e5efaac0df4d2a1.html