JAVA应用DES实现对称加(解)密

2012-03-03 23:31:05|?次阅读|上传:wustguangh【已有?条评论】发表评论

关键词:Java, 加密/解密|来源:唯设编程网

DES算法全称为Data Encryption Standard,即数据加密算法,它是IBM公司于1975年研究成功并公开发表,其密钥长度为56位,明文按64位进行分组,将分组后的明文组和56 位的密钥按位替代或交换的方法形成密文组的加密方法。DES算法的入口参数有三个:Key、Data、Mode。其中Key为8个字节共64位,是DES 算法的工作密钥;Data也为8个字节64位,是要被加密或被解密的数据;Mode为DES的工作方式,有两种:加密或解密。

DES加密算法特点:分组比较短、密钥太短、密码生命周期短、运算速度较慢。

DES 工作的基本原理是,其入口参数有三个:key、 data、mode。 key为加密解密使用的密钥 ,data为加密解密的数据,mode为其工作模式。当模式为加密模式时,明文按照64 DES加密算法位进行分组,形成明文组,key用于对数据加密,当模式为解密模式时,key用于对数据解密。实际运用中,密钥只用到了64位中的56位, 这样才具有高的安全性。

DES( Data Encryption Standard)算法,于1977年得到美国政府的正式许可,是一种用56位密钥来加密64位数据的方法。虽然56位密钥的DES算法已经风光不在,而 且常有用Des加密的明文被破译的报道,但是了解一下昔日美国的标准加密算法总是有益的,而且目前DES算法得到了广泛的应用,在某些场合,仍然发挥着余 热。

DES算法把64位的明文输入块变为64位的密文输出块,它所使用的密钥也是64位,其算法主要分为两步:

1.初始置换

其 功能是把输入的64位数据块按位重新组合,并把输出分为L0、R0两部分,每部分各长3 2位,其置换规则为将输入的第58位换到第一位,第50位换到第2位……依此类推,最后一位是原来的第7位。L0、R0则是换位输出后的两部分,L0是输 出的左32位,R0是右32位,例:设置换前的输入值为D1D2D3……D64,则经过初始置换后的结果为:L0=D58D50……D8; R0=D57D49……D7。

2.逆置换

经过16次迭代运算后,得到L16、R16,将此作为输入,进行逆置换,逆置换正好是初始置换的逆运算,由此即得到密文输出。

下面介绍DES加密方法在JAVA编程中的实际应用:
示例:

/**
 * 
 */
package FamilyAsset.Utility.Security;

import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

/**
 * 实现DES加密、解密的工具类
 */
public class DES {
	/**密钥*/
	private static final String DES_CRYPT_KEY = "!#$%^&*Z.2()-+{}";
	/**加密方法*/
	private final static String DES = "DES";

	/**
	 * 加密
	 * @param src 数据源
	 * @param key 密钥,长度必须是8的倍数
	 * @return 返回加密后的数据
	 * @throws Exception
	 */
	public static byte[] encrypt(byte[] src, byte[] key) throws Exception {
		// DES算法要求有一个可信任的随机数源
		SecureRandom sr = new SecureRandom();
		// 从原始密匙数据创建DESKeySpec对象
		DESKeySpec dks = new DESKeySpec(key);
		// 创建一个密匙工厂,然后用它把DESKeySpec转换成
		// 一个SecretKey对象
		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
		SecretKey securekey = keyFactory.generateSecret(dks);
		// Cipher对象实际完成加密操作
		Cipher cipher = Cipher.getInstance(DES);
		// 用密匙初始化Cipher对象
		cipher.init(Cipher.ENCRYPT_MODE, securekey, sr);
		// 现在,获取数据并加密
		// 正式执行加密操作
		return cipher.doFinal(src);
	}

	/**
	 * 解密
	 * @param src 数据源
	 * @param key 密钥,长度必须是8的倍数
	 * @return 返回解密后的原始数据
	 * @throws Exception
	 */
	public static byte[] decrypt(byte[] src, byte[] key) throws Exception {
		// DES算法要求有一个可信任的随机数源
		SecureRandom sr = new SecureRandom();
		// 从原始密匙数据创建一个DESKeySpec对象
		DESKeySpec dks = new DESKeySpec(key);
		// 创建一个密匙工厂,然后用它把DESKeySpec对象转换成
		// 一个SecretKey对象
		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
		SecretKey securekey = keyFactory.generateSecret(dks);
		// Cipher对象实际完成解密操作
		Cipher cipher = Cipher.getInstance(DES);
		// 用密匙初始化Cipher对象
		cipher.init(Cipher.DECRYPT_MODE, securekey, sr);
		// 现在,获取数据并解密
		// 正式执行解密操作
		return cipher.doFinal(src);
	}

	/**
	 * 密码解密
	 * @param data
	 * @return
	 * @throws Exception
	 */
	public final static String decrypt(String data) {
		try {
			return new String(decrypt(hex2byte(data.getBytes()),DES_CRYPT_KEY.getBytes()));
		} catch (Exception e) {
		}
		return null;
	}

	/**
	 * 密码加密
	 * @param password
	 * @return
	 * @throws Exception
	 */
	public final static String encrypt(String password) {
		try {
			return byte2hex(encrypt(password.getBytes(),DES_CRYPT_KEY.getBytes()));
		} catch (Exception e) {
		}
		return null;
	}

	/**
	 * byte[]转换成String
	 * @param b
	 * @return
	 */
	public static String byte2hex(byte[] b) {
		String hs = "";
		String stmp = "";
		for (int n = 0; n < b.length; n++) {
			stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
			if (stmp.length() == 1)
				hs = hs + "0" + stmp;
			else
				hs = hs + stmp;
		}
		return hs.toUpperCase();
	}
	/**
	 * String转成byte[]
	 * @param b
	 * @return
	 */
	public static byte[] hex2byte(byte[] b) {
		if ((b.length % 2) != 0)
			throw new IllegalArgumentException("长度不是偶数");
		byte[] b2 = new byte[b.length / 2];
		for (int n = 0; n < b.length; n += 2) {
			String item = new String(b, n, 2);
			b2[n / 2] = (byte) Integer.parseInt(item, 16);
		}
		return b2;
	}
}

测试代码:

package FamilyAsset.Utility.Starup;

import FamilyAsset.Utility.Security.DES;
import FamilyAsset.Utility.Security.MD5;

public class Test {
	public static void main(String[] args) {
		//DES测试
		String encrypt=DES.encrypt("测试字符串1!测试字符串2!");
		String decrypt=DES.decrypt(encrypt);
		System.out.println(encrypt);
		System.out.println(decrypt);
		//MD5测试
		System.out.println(MD5.getMD5("I LOVE YOU!") );
	}
}

结果如下:

发表评论0条 】
网友评论(共?条评论)..
JAVA应用DES实现对称加(解)密