Java加密的艺术道路 第一篇 AES加密

笔者学识浅薄,对加密的研究也只是刚刚起步,很多深入的知识有待挖掘,还没有到达研究原理的高度和深度。文章的重心在简单的应用Java中AES中的一种加密方式。

第一 创建一个Java 对象,这个Password对象有4个属性分别是  明文、密文、密钥、和加密算法。

public class Password {

	/**
	 * 密文16进制字符串
	 */
	private String ciphertext;

	/**
	 * 明文
	 */
	private String plaintext;
	/**
	 * 密钥 16进制密钥
	 */
	private String secretKey;
	/**
	 * 算法
	 */
	private String algorithm;

	public String getAlgorithm() {
		return algorithm;
	}

	public void setAlgorithm(String algorithm) {
		this.algorithm = algorithm;
	}

	public String getCiphertext() {
		return ciphertext;
	}

	public String getPlaintext() {
		return plaintext;
	}

	public String getSecretKey() {
		return secretKey;
	}

	public void setCiphertext(String ciphertext) {
		this.ciphertext = ciphertext;
	}

	public void setPlaintext(String plaintext) {
		this.plaintext = plaintext;
	}

	public void setSecretKey(String secretKey) {
		this.secretKey = secretKey;
	}
}

第二 创建一个工具类Convert,来处理字节数组和十六进制字符串之间的相互转化。

public class Convert {

	private static Convert convert;

	private Convert() {

	}

	/**
	 * 
	 * @description TODO 通过这样的方式来创建单列
	 * @return
	 * @return Convert
	 */
	public static Convert getInstance() {
		if (convert == null)
			convert = new Convert();
		return convert;
	}

	/**
	 * 
	 * @description TODO 将字节数组转化为十六进制字符串
	 * @param bytes
	 * @return
	 * @return String
	 */
	public static String bytes2HexString(byte[] bytes) {

		if (bytes != null && bytes.length > 0) {
			StringBuffer sb = new StringBuffer();
			for (int i = 0; i < bytes.length; i++) {
				String hex = Integer.toHexString(bytes[i] & 0xFF);
				if (hex.length() < 2)
					hex = '0' + hex;
				sb.append(hex.toUpperCase());
			}
			return sb.toString();
		}
		return null;

	}

	/**
	 * 
	 * @description TODO 十六进制字符串转字节数组
	 * @param hexString
	 * @return
	 * @return byte[]
	 */
	public static byte[] hexStringToBytes(String hexString) {

		if (hexString != null && !"".equals(hexString)) {
			hexString = hexString.toUpperCase();
			int length = hexString.length() / 2;
			char[] hexChars = hexString.toCharArray();
			byte[] bytes = new byte[length];
			for (int i = 0; i < length; i++) {
				int pos = i * 2;
				bytes[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
			}
			return bytes;
		}
		return null;

	}

	/**
	 * 
	 * @description TODO 字符转化字节
	 * @param c
	 * @return
	 * @return byte
	 */
	private static byte charToByte(char c) {
		return (byte) "0123456789ABCDEF".indexOf(c);
	}
}

第三步创建我们的加密和解密的AES算法类

public interface Algorithm {

	public Password encrypt(Password password) throws Exception;

	public Password decrypt(Password password) throws Exception;
}


public class AESAlgorithm implements Algorithm {

	private static int AES_KEY_SIZE = 128;

	@Override
	public Password encrypt(Password password) throws Exception {

		/**
		 * 生成密钥
		 */
		KeyGenerator generator = KeyGenerator.getInstance("AES");
		generator.init(AES_KEY_SIZE);
		SecretKey key = generator.generateKey();
		/**
		 * 将密钥转为16进制字符串
		 */
		password.setSecretKey(Convert.bytes2HexString(key.getEncoded()));
		Cipher cipher = Cipher
				.getInstance(EncryptionAlgorithm.AES_CBC_PKCS5_PADDING.getAlgorithm());
		AlgorithmParameterSpec iv = new IvParameterSpec(getIV());
		cipher.init(Cipher.ENCRYPT_MODE, key, iv);

		byte[] encryptBytes = cipher.doFinal(password.getPlaintext().getBytes(
				"UTF-8"));
		/**
		 * 将加密结果转化为16进制字符串
		 */
		password.setCiphertext(Convert.bytes2HexString(encryptBytes));
		return password;
	}

	@Override
	public Password decrypt(Password password) throws Exception {
		if (password.getCiphertext() != null && password.getCiphertext() != null
				&& !"".equals(password.getSecretKey())
				&& !"".equals(password.getCiphertext())) {
			byte[] ciphertext = Convert.hexStringToBytes(password.getCiphertext());
			byte[] key = Convert.hexStringToBytes(password.getSecretKey());
			Key secretKey = new SecretKeySpec(key, "AES");
			AlgorithmParameterSpec iv = new IvParameterSpec(getIV());
			Cipher cipher = Cipher
					.getInstance(EncryptionAlgorithm.AES_CBC_PKCS5_PADDING.getAlgorithm());
			cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);
			byte[] decryptBytes = cipher.doFinal(ciphertext);
			password.setPlaintext(new String(decryptBytes, "UTF-8"));
			return password;
		}
		return password;
	}

	static byte[] getIV() {
		String iv = "1234567812345678"; // IV length: must be 16 bytes long
		return iv.getBytes();
	}

}


第四  枚举类型来穷举AES加密的四种加密方式

public enum EncryptionAlgorithm {

	AES_CBC_NO_PADDING("AES/CBC/NoPadding"),

	AES_CBC_PKCS5_PADDING("AES/CBC/PKCS5Padding"),

	AES_ECB_NO_PADDING("AES/ECB/NoPadding"),

	AES_ECB_PKCS5_PADDING("AES/ECB/PKCS5Padding");

	private String algorithm;

	private EncryptionAlgorithm(String algorithm) {
		this.algorithm = algorithm;
	}

	public String getAlgorithm() {
		return algorithm;
	}

}





最后有几点需要说明  

1、AES加密后的密钥和密文为了方便记录存储,转化为十六进制字符串;

2、密钥和密文两个条件来解密还原成明文;

3、文中只是简单介绍了AES一种方式(AES/ECB/PKCS5Padding)的加密方式的应用。






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值