`

Java密码学(3)——对称加密算法

 
阅读更多

对称加密算法的加密密钥和解密密钥相同,用密钥对原数据加密得到密文,对密文解密密得到明文,解密算法是加密算法的逆运算。

DES是最具代表性的对称加密算法,DESede是DES算法的变种又称3DES。DES算法有ecb和cbc两种模式。 AES算法作为DES的替代,更安全,性能更好。

 

  • DES算法

模型图如下

 

这里采用单DES的ECB模式用代码实现 

	/**
	 * DES ECB模式加解密
	 * @param key
	 * @param data
	 * @param mode 0-加密,1-解密
	 * @return
	 */
	public static String desecb(String key, String data, int mode) {
		try {
			DESKeySpec dks = new DESKeySpec(Hex.decodeHex(key.toCharArray()));
			SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
			SecretKey secretKey = keyFactory.generateSecret(dks);
			
			Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding");
			if(mode==0){
				cipher.init(Cipher.ENCRYPT_MODE, secretKey);
			}else{
				cipher.init(Cipher.DECRYPT_MODE, secretKey);
			}
			return Hex.encodeHexString(cipher.doFinal(Hex.decodeHex(data.toCharArray())));
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		} catch (DecoderException e) {
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (InvalidKeySpecException e) {
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {
			e.printStackTrace();
		} catch (BadPaddingException e) {
			e.printStackTrace();
		}
		return null;
	}

 测试代码

	String key = "404142434445464748494a4b4c4d4e4f";
	String data = "404142434445464748494a4b4c4d4e4f";
	String encode = desecb(key, data, 1);
	System.out.println("DES加密后的密文:"+encode);
	String decode = desecb(key, encode, 0);
	System.out.println("DES解密后的明文:"+decode);

 运行结果

DES加密后的密文:f2db549c724485f5eff4e2f84fd31835
DES解密后的明文:404142434445464748494a4b4c4d4e4f

注意:DES算法中key和data必须为8字节整数倍的HexString

 

  • PBE算法

 PBE——Password Based Encryption,基于口令加密。

DES算法密钥长度是16字节,3DES密钥长度是32字节,不方便记忆。PBE算法用口令替代密钥,口令方便记忆。比如我们登录windows操作系统就要输入一个口令。

PBE算法可以看成是消息摘要算法+对称加密算法。我们需要一个口令和盐,盐是一个随机信息。通过消息摘要算法,对口令+盐生成密钥,该密钥用于对称加密。

模型如下

PBEWITHMD5andDES模式的PBE算法实现代码

	/**
	 * 基于口令加密PBE算法
	 * @param password 口令
	 * @param data     数据
	 * @param salt     盐
	 * @param mode
	 *            0-加密,1-解密
	 * @return
	 */
	public static String pbe(String password, String data, byte[] salt, int mode){
		try {
			//转换密码
			PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
			SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWITHMD5andDES");
			SecretKey secretKey = keyFactory.generateSecret(keySpec);
			
			PBEParameterSpec paramSpec = new PBEParameterSpec(salt, 100);
			Cipher cipher = Cipher.getInstance("PBEWITHMD5andDES");
			if (mode == 0) {
				cipher.init(Cipher.ENCRYPT_MODE, secretKey, paramSpec);
			} else {
				cipher.init(Cipher.DECRYPT_MODE, secretKey, paramSpec);
			}
			return Hex.encodeHexString(cipher.doFinal(Hex.decodeHex(data
					.toCharArray())));
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (InvalidKeySpecException e) {
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			e.printStackTrace();
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		} catch (InvalidAlgorithmParameterException e) {
			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {
			e.printStackTrace();
		} catch (BadPaddingException e) {
			e.printStackTrace();
		} catch (DecoderException e) {
			e.printStackTrace();
		} 
		return null;
	}

 测试代码

		String password = "yel";
		System.out.println("口令:"+password);
		String data = "404142434445464748494a4b4c4d4e4f";
		System.out.println("原始数据:"+data);
		byte[] salt = new SecureRandom().generateSeed(8);
		System.out.println("盐:"+Hex.encodeHexString(salt));
		String encode = pbe(password, data, salt, 0);
		System.out.println("PBE加密后的密文:" + encode);
		String decode = pbe(password, encode, salt, 1);
		System.out.println("PBE解密后的明文:" + decode);

 运行结果

口令:yel
原始数据:404142434445464748494a4b4c4d4e4f
盐:d6bae74f476d8f6f
PBE加密后的密文:290fae52e24e874146ca2dad8986876cc117730f09ec46ac
PBE解密后的明文:404142434445464748494a4b4c4d4e4f

 

  • 大小: 27 KB
  • 大小: 29.7 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics