1、参考文章:
1.1对称加密算法;
1.2DES算法详细设计;
2、参考代码
2.1、DESUtils
2.2、Encryp-Demo
3.对称加密算法
3.1 定义
对称加密算法是应用较早的加密算法,技术成熟。在对称加密算法中,数据发信方将明文(原始数据)和加密密钥(mi yue)一起经过特殊加密算法处理后,使其变成复杂的加密密文发送出去。收信方收到密文后,若想解读原文,则需要使用加密用过的密钥及相同算法的逆算法对密文进行解密,才能使其恢复成可读明文。在对称加密算法中,使用的密钥只有一个,发收信双方都使用这个密钥对数据进行加密和解密,这就要求解密方事先必须知道加密密钥。
3.2 优缺点
优点:算法公开、计算量小、加密速度快、加密效率高。
缺点:
(1)交易双方都使用同样钥匙,安全性得不到保证。
(2)每对用户每次使用对称加密算法时,都需要使用其他人不知道的惟一钥匙,这会使得发收信双方所拥有的钥匙数量呈几何级数增长,密钥管理成为用户的负担。对称加密算法在分布式网络系统上使用较为困难,主要是因为密钥管理困难,使用成本较高。
3.3 常用对称加密算法
基于“对称密钥”的加密算法主要有DES、3DES(TripleDES)、AES、RC2、RC4、RC5和Blowfish等。本文只介绍最常用的对称加密算法DES、3DES(TripleDES)和AES。
3.4、DES加密算法的几种模式:
3.4.1、参考文章 ;
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实际上是3-DES)
DESede/CBC/NoPadding (168)
DESede/CBC/PKCS5Padding (168)
DESede/ECB/NoPadding (168)
DESede/ECB/PKCS5Padding (168)
3.4.2:需要留意的坑:
由于加密时会自动填充到8字节(64bit),那么在我们进行字节数组到字串的转化过程中,可以把它填补的不可见字符改变了,所以解密时会导致异常,用base64解决
4、代码:
package com.jm;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
import org.apache.commons.codec.binary.Hex;
/**
* @Createtime 2014年12月5日 14:22:00
* @author Lxz
*
*/
public class DESUtil {
/**
* UTF-8编码
*/
public static final String ENCODED_UTF8 = "UTF-8";
/**
* GBK编码
*/
public static final String ENCODED_GBK = "GBK";
/**
* GB2312编码
*/
public static final String ENCODED_GB2312 = "GB2312";
/**
* ISO8859-1编码
*/
public static final String ENCODED_ISO88591 = "ISO8859-1";
/**
* ASCII编码
*/
public static final String ENCODED_ASCII = "ASCII";
/**
* UNICODE编码
*/
public static final String ENCODED_UNICODE = "UNICODE";
/**
* CBC加密模式
*/
public static final String CIPHER_INSTANCE_CBC = "DES/CBC/PKCS5Padding";
/**
* ECB加密模式
*/
public static final String CIPHER_INSTANCE_ECB = "DES/ECB/PKCS5Padding";
/**
* DES加密
*
* @param HexString
* 字符串(16位16进制字符串)
* @param keyStr
* 密钥16个1
* @throws Exception
*/
public static String ENCRYPTMethod(String HexString, String keyStr)
throws Exception {
String jmstr = "";
try {
byte[] theKey = null;
//从给定的密钥中截取生成真正的密钥来源,保证加密解密算法的唯一性,避免数据的轻易可逆;
String jqstr = getstrByte(keyStr).substring(0,8).toUpperCase();
theKey = jqstr.getBytes(ENCODED_ASCII);
//Ciper[名词]:零、暗号、密码本;
//获取CIPHER_INSTANCE_CBC模式下的密码本;
Cipher cipher = Cipher.getInstance(CIPHER_INSTANCE_CBC);
//生成secrecKey;
DESKeySpec desKeySpec = new DESKeySpec(theKey);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
IvParameterSpec iv = new IvParameterSpec(theKey);
cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
byte[] theCph = cipher.doFinal(HexString.getBytes(ENCODED_GB2312));
jmstr = toHexString(theCph).toUpperCase();
jmstr = toHexString(theCph);
} catch (Exception e) {
e.printStackTrace();
return null;
}
return jmstr;
}
public static String getstrByte(String str){
if(null == str){
throw new IllegalArgumentException(
"str is null!");
}
MessageDigest messageDigest = getMessageDigest();
byte[] digest;
try {
digest = messageDigest.digest(str.getBytes("ASCII"));
} catch (UnsupportedEncodingException e) {
throw new IllegalStateException("ASCII not supported!");
}
return new String(Hex.encodeHex(digest));
}
protected static final MessageDigest getMessageDigest() {
String algorithm = "MD5";
try {
return MessageDigest.getInstance(algorithm);
} catch (NoSuchAlgorithmException e) {
throw new IllegalArgumentException("No such algorithm ["
+ algorithm + "]");
}
}
/**
* DES加密
* @param HexString 字符串(16位16进制字符串)
* @param keyStr 密钥16个1
* @param keyENCODED Keybyte转换编码
* @param HexStringENCODED 要加密值的转换byte编码
* @param CipherInstanceType 需要加密类型
* @return
* @throws Exception
*/
public static String ENCRYPTMethod(String HexString, String keyStr,String keyENCODED,String HexStringENCODED,String CipherInstanceType)
throws Exception {
String jmstr = "";
try {
byte[] theKey = null;
String jqstr = getstrByte(keyStr).substring(0,8).toUpperCase();
theKey = jqstr.getBytes(keyENCODED);
Cipher cipher = Cipher.getInstance(CipherInstanceType);
DESKeySpec desKeySpec = new DESKeySpec(theKey);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
IvParameterSpec iv = new IvParameterSpec(theKey);
cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
byte[] theCph = cipher.doFinal(HexString.getBytes(HexStringENCODED));
jmstr = toHexString(theCph).toUpperCase();
jmstr = toHexString(theCph);
} catch (Exception e) {
e.printStackTrace();
return null;
}
return jmstr;
}
public static String toHexString(byte b[]) {
StringBuffer hexString = new StringBuffer();
for (int i = 0; i < b.length; i++) {
String plainText = Integer.toHexString(0xff & b[i]);
if (plainText.length() < 2)
plainText = "0" + plainText;
hexString.append(plainText);
}
return hexString.toString();
}
/**
* DES解密方法
* @param message 需要解密字符串
* @param key 解密需要的KEY
* @param keyENCODED 解密KEY转换编码
* @param HexStringENCODED 解密字符串转换编码
* @param CipherInstanceType 解密类型
* @return
* @throws Exception
*/
public static String decrypt(String message, String key,String keyENCODED,String HexStringENCODED,String CipherInstanceType) throws Exception {
byte[] bytesrc = convertHexString(message);
byte[] theKey = null;
String jqstr = getstrByte(key).substring(0,
8).toUpperCase();
theKey = jqstr.getBytes(keyENCODED);
Cipher cipher = Cipher.getInstance(CipherInstanceType);
DESKeySpec desKeySpec = new DESKeySpec(theKey);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
IvParameterSpec iv = new IvParameterSpec(theKey);
cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);
byte[] retByte = cipher.doFinal(bytesrc);
return new String(retByte,HexStringENCODED);
}
/**
* DES解密方法,解密方法和加密方法应该是对称的;
* @param message
* @param key
* @return
* @throws Exception
*/
public static String decrypt(String message, String key) throws Exception {
byte[] bytesrc = convertHexString(message);
byte[] theKey = null;
String jqstr = getstrByte(key).substring(0,
8).toUpperCase();
theKey = jqstr.getBytes(ENCODED_ASCII);
Cipher cipher = Cipher.getInstance(CIPHER_INSTANCE_CBC);
DESKeySpec desKeySpec = new DESKeySpec(theKey);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
IvParameterSpec iv = new IvParameterSpec(theKey);
cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);
byte[] retByte = cipher.doFinal(bytesrc);
return new String(retByte,ENCODED_GB2312);
}
public static byte[] convertHexString(String ss) {
byte digest[] = new byte[ss.length() / 2];
for (int i = 0; i < digest.length; i++) {
String byteString = ss.substring(2 * i, 2 * i + 2);
int byteValue = Integer.parseInt(byteString, 16);
digest[i] = (byte) byteValue;
}
return digest;
}
public static void main(String[] args) throws Exception {
String key = "27650099-564A-4869-99B3-363F8129C0CD";
String value = "张三内部购房百分点办法对你表白";
String jiami = value;
System.out.println("加密数据:" + jiami);
String a = ENCRYPTMethod(jiami, key).toUpperCase();
System.out.println("加密后的数据为:" + a);
String b = decrypt(a, key);
System.out.println("解密后的数据:" + b);
}
}