使用JAVA对字符串进行DES加密解密

总的来说,代码大部分是从网上抄的,网上一搜就有很多类似的版本,但是没有一个是可以直接用的,所以做了一些改进,现在是比较完善的版本了。

网上的代码里,在密码加密那块,代码写错了,所以有严重的问题:

1.密码只支持8位或8位以上,低于8位都会出错。

2.密码有效值只有8位,也就是说使用密码‘12345678’,‘123456789’,‘12345678901234’.....等等,加密出来的数据都是一样的。

3.密码并不唯一,我试过使用‘12345678’与‘12345679’这两个密码效果是一样的。而且任意一位上都有至少两个相邻的字符,加密出来的效果是一样的。结果就是可能你可以拿一个全完不相同的密码,来解密。

4.修正linux系统下,每次密码随机变化的BUG。

我的版本应该是正确的写法,不存在以上问题。

 

import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;

public class SecretTool {
	private final static String DES = "DES";
	
	/**
	 * 加密
	 * @param data 数据源
	 * @param 密钥,长度任意
	 * @return 返回加密后的数据
	 */
	public static String encrypt(String data, String password) {
		try {
			return byte2hex(encrypt(data.getBytes(), password.getBytes()));
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
	/**
	 * 解密
	 * @param data
	 * @param 密钥,长度任意
	 * @return 返回加密后的数据
	 */
	public static String decrypt(String data, String password) {
		try {
			return new String(decrypt(hex2byte(data), password.getBytes()));
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * DES加密
	 * 
	 * @param src
	 *            数据源
	 * @param key
	 *            密钥,长度任意
	 * @return 返回加密后的数据
	 * @throws Exception
	 */
	private static byte[] encrypt(byte[] src, byte[] key) throws Exception {
		// DES算法要求有一个可信任的随机数源
		SecureRandom sr = new SecureRandom();
		
		// 从原始密匙数据创建一个SecretKey对象
		KeyGenerator kgen = KeyGenerator.getInstance(DES);
                  SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
                  secureRandom.setSeed(key);		
		// Cipher对象实际完成加密操作
		Cipher cipher = Cipher.getInstance(DES);
		// 用密匙初始化Cipher对象
		cipher.init(Cipher.ENCRYPT_MODE, secretKey, sr);
		// 现在,获取数据并加密
		// 正式执行加密操作
		return cipher.doFinal(src);
	}

	/**
	 * DES解密
	 * 
	 * @param src
	 *            数据源
	 * @param key
	 *            密钥,长度任意
	 * @return 返回解密后的原始数据
	 * @throws Exception
	 */
	private static byte[] decrypt(byte[] src, byte[] key) throws Exception {
		// DES算法要求有一个可信任的随机数源
		SecureRandom sr = new SecureRandom();

		// 从原始密匙数据创建一个SecretKey对象
		KeyGenerator kgen = KeyGenerator.getInstance(DES);
                  SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
                  secureRandom.setSeed(key); 
		// Cipher对象实际完成解密操作
		Cipher cipher = Cipher.getInstance(DES);
		// 用密匙初始化Cipher对象
		cipher.init(Cipher.DECRYPT_MODE, secretKey, sr);
		// 现在,获取数据并解密
		// 正式执行解密操作
		return cipher.doFinal(src);
	}

	/**
	 * 将二进制转化为16进制字符串
	 * 
	 * @param b
	 *            二进制字节数组
	 * @return String
	 */
	private 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();
	}

	/**
	 * 十六进制字符串转化为2进制
	 * 
	 * @param hex
	 * @return
	 */
	private static byte[] hex2byte(String hex) {
		byte[] tmp = hex.getBytes();
		byte[] ret = new byte[tmp.length / 2];
		for (int i = 0; i < ret.length; i++) {
			ret[i] = uniteBytes(tmp[i * 2], tmp[i * 2 + 1]);
		}
		return ret;
	}
	
	/**  
     * 将两个ASCII字符合成一个字节; 如:"EF"--> 0xEF  
     *   
     * @param src0  
     *            byte  
     * @param src1  
     *            byte  
     * @return byte  
     */  
    private static byte uniteBytes(byte src0, byte src1) {   
        byte _b0 = Byte.decode("0x" + new String(new byte[] { src0 }))   
                .byteValue();   
        _b0 = (byte) (_b0 << 4);   
        byte _b1 = Byte.decode("0x" + new String(new byte[] { src1 }))   
                .byteValue();   
        byte ret = (byte) (_b0 ^ _b1);   
        return ret;   
    }

	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception {
		String source = "This is for DES test";
		String temp = SecretTool.encrypt(source, "123456");
		System.out.println(temp + ":" + temp.length());
		String result2 = SecretTool.decrypt(temp, "123456");
		System.out.println(result2 + ":" + result2.length());
		System.out.println(source.equals(result2));
	}

}

你可能感兴趣的:(JAVA,LINUX)