MOYUN(/Java/SQL/Linux/DevOps/运维/架构/管理/敏捷/开发)

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

随着对称密码的发展,DES数据加密标准算法由于密钥长度较小(56位),已经不适应当今分布式开放网络对数据加密安全性的要求,因此1997年NIST公开征集新的数据加密标准,即AES[1]。经过三轮的筛选,比利时Joan Daeman和Vincent Rijmen提交的Rijndael算法被提议为AES的最终算法。此算法将成为美国新的数据加密标准而被广泛应用在各个领域中。尽管人们对AES还有不同的看法,但总体来说,AES作为新一代的数据加密标准汇聚了强安全性、高性能、高效率、易用和灵活等优点。AES设计有三个密钥长度:128,192,256位,相对而言,AES的128密钥比DES的56密钥强1021倍[2]。AES算法主要包括三个方面:轮变化、圈数和密钥扩展。本文以128为例,介绍算法的基本原理;结合AVR汇编语言,实现高级数据加密算法AES。

AES是分组密钥,算法输入128位数据,密钥长度也是128位。用Nr表示对一个数据分组加密的轮数(加密轮数与密钥长度的关系如表1所列)。每一轮都需要一个与输入分组具有相同长度的扩展密钥Expandedkey(i)的参与。由于外部输入的加密密钥K长度有限,所以在算法中要用一个密钥扩展程序(Keyexpansion)把外部密钥K扩展成更长的比特串,以生成各轮的加密和解密密钥。

AES加密算法原理
.................................................................................................................................

 加密前需要的参数encoding声明为以哪种字符方式加密,AES对称加密,KEY为密钥

	private final static String encoding      = "UTF-8";
	private final static String AES  = "AES";
	private final static String KEY  = "xxxxsfddsfdsfsdfds";
	
	/**
	* AES加密
	* **/
	public static String encryptAES(String content) {
		byte[] encryptResult = encrypt(content);
		String encryptResultStr = parseByte2HexStr(encryptResult);
		// BASE64位加密
		encryptResultStr = ebotongEncrypto(encryptResultStr);
		return encryptResultStr;
	}

	/**
	* AES解密
	* @param encryptResultStr
	* @return String
	* **/
	public static String decryptAES(String encryptResultStr) {
		
		// BASE64位解密
		String decrpt = ebotongDecrypto(encryptResultStr);
		byte[] decryptFrom = parseHexStr2Byte(decrpt);
		byte[] decryptResult = decrypt(decryptFrom);
		return new String(decryptResult);
	}

	 
	/**
	* 加密字符串
	* */
	public static String ebotongEncrypto(String str) {

		BASE64Encoder base64encoder = new BASE64Encoder();
		String result = str;
		if (str != null && str.length() > 0) {
			try {
		
				byte[] encodeByte = str.getBytes(encoding);		
				result = base64encoder.encode(encodeByte);
			}catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
		}

		//base64加密超过一定长度会自动换行 需要去除换行符
		return result.replaceAll("\r\n", "").replaceAll("\r", "").replaceAll("\n", "");
	}

	/**
	* 解密字符串
	* */
	public static String ebotongDecrypto(String str) {
		
		BASE64Decoder base64decoder = new BASE64Decoder();
		try {
			byte[] encodeByte = base64decoder.decodeBuffer(str);
			return new String(encodeByte);
		} catch (IOException e) {
			e.printStackTrace();
			return str;
		}
	}

	 
	 
	/**
	* 加密
	*
	* @param content 需要加密的内容
	* @param password  加密密码
	* @return
	*/
	public static byte[] encrypt(String content) {
		
		try {
			KeyGenerator kgen = KeyGenerator.getInstance(AES);
			SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
			secureRandom.setSeed(KEY.getBytes());
			kgen.init(128, secureRandom);
			SecretKey secretKey = kgen.generateKey();
			byte[] enCodeFormat = secretKey.getEncoded();
			SecretKeySpec key = new SecretKeySpec(enCodeFormat, AES);
			Cipher cipher = Cipher.getInstance(AES);// 创建密码器
			byte[] byteContent = content.getBytes();
			cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
			byte[] result = cipher.doFinal(byteContent);
			return result; // 加密
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			e.printStackTrace();
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {
			e.printStackTrace();
		} catch (BadPaddingException e) {
			e.printStackTrace();
		}
		return null;
	}

	 
	 
	/**解密
	* @param content  待解密内容
	* @param password 解密密钥
	* @return
	*/
	public static byte[] decrypt(byte[] content) {

		try {
				KeyGenerator kgen = KeyGenerator.getInstance(AES);
				//kgen.init(128, new SecureRandom(AESUtilsPassWordKey.PASSWORD_KEY.getBytes()));
				SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
				secureRandom.setSeed(KEY.getBytes());
				kgen.init(128, secureRandom);
				SecretKey secretKey = kgen.generateKey();
				byte[] enCodeFormat = secretKey.getEncoded();
				SecretKeySpec key = new SecretKeySpec(enCodeFormat, AES);
				Cipher cipher = Cipher.getInstance(AES);// 创建密码器
				cipher.init(Cipher.DECRYPT_MODE, key);// 初始化
				byte[] result = cipher.doFinal(content);
				return result; // 加密
			} catch (NoSuchAlgorithmException e) {
				e.printStackTrace();
			} catch (NoSuchPaddingException e) {
				e.printStackTrace();
			} catch (InvalidKeyException e) {
				e.printStackTrace();
			} catch (IllegalBlockSizeException e) {
				e.printStackTrace();
			} catch (BadPaddingException e) {
				e.printStackTrace();
		}
		return null;
	}

	 
	/**将16进制转换为二进制 解密
	* @param hexStr
	* @return
	*/
	public static byte[] parseHexStr2Byte(String hexStr) {

		if (hexStr.length() < 1)
			return null;	
		byte[] result = new byte[hexStr.length()/2];
		for (int i = 0;i< hexStr.length()/2; i++) {
			int high = Integer.parseInt(hexStr.substring(i*2, i*2+1), 16);
			int low = Integer.parseInt(hexStr.substring(i*2+1, i*2+2), 16);
			result[i] = (byte) (high * 16 + low);
		}
		return result;
	}

    /** 
	* 将二进制转换成16进制 加密
	* @param buf
	* @return
	*/
	public static String parseByte2HexStr(byte buf[]) {
		
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < buf.length; i++) {
			String hex = Integer.toHexString(buf[i] & 0xFF);
			if (hex.length() == 1) {
				hex = '0' + hex;
			}
			sb.append(hex.toUpperCase());
		}
		return sb.toString();
	}
	
	public static void main(String[] args) {

		String content = "中文测试";
		String encryptResultStr = encryptAES(content);
		System.out.println("加密前: "+content);
		System.out.println("加密后: "+encryptResultStr);
		System.out.println("解密后: "+decryptAES(encryptResultStr));
	}

  

posted on 2013-11-15 23:15  moyun-  阅读(6564)  评论(0编辑  收藏  举报