AES對數據進行加密與解密


隨着對稱密碼的發展,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));
	}

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM