天天看點

對稱加密算法(3):AES

一.AES:AES加密算法即密碼學中的進階加密标準(Advanced Encryption Standard,AES),又稱Rijndael加密法,是美國聯邦政府采用的一種區塊加密标準。這個标準用來替代原先的DES,已經被多方分析且廣為全世界所使用。經過五年的甄選流程,進階加密标準由美國國家标準與技術研究院 (NIST)于2001年11月26日釋出于FIPS PUB 197,并在2002年5月26日成為有效的标準。2006年,進階加密标準已然成為對稱密鑰加密中最流行的算法之一。該算法為比利時密碼學家Joan Daemen和Vincent Rijmen所設計,結合兩位作者的名字,以Rijndael之命名之,投稿進階加密标準的甄選流程。(Rijdael的發音近于 "Rhinedoll"。)

二.優缺點:AES在軟體及硬體上都能快速地加解密,相對來說較易于實作,且隻需要很少的存儲器。

三.原理:AES算法基于排列和置換運算。排列是對資料重新進行安排,置換是将一個資料單元替換為另一個。AES 使用幾種不同的方法來執行排列和置換運算。AES是一個疊代的、對稱密鑰分組的密碼,它可以使用128、192 和 256 位密鑰,并且用 128 位(16位元組)分組加密和解密資料。與公共密鑰密碼使用密鑰對不同,對稱密鑰密碼使用相同的密鑰加密和解密資料。通過分組密碼傳回的加密資料的位數與輸入資料相同。疊代加密使用一個循環結構,在該循環中重複置換和替換輸入資料。

四.實作方式(java):

注意!!!:如果是自定義的秘鑰,必須指定秘鑰的長度,DES,3DES,AES 都一樣 

/**
	 *  AES 生成秘鑰 ,系統生成預設的秘鑰,自定義長度
	 * @return
	 * @throws Exception
	 */
	public static byte [] JDK_AES_GetSecretKey() throws Exception{
		KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
		keyGenerator.init(128);   // new SecureRandom() 預設長度 
		Key secretKey = keyGenerator.generateKey();
		return secretKey.getEncoded();
	}
	
	/**
	 * AES 生成秘鑰 ,自定義的秘鑰,生成預設的秘鑰長度
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static byte [] JDK_AES_GetSecretKey(String key) throws Exception{
		KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
		keyGenerator.init(128,new SecureRandom(key.getBytes()));
		Key secretKey = keyGenerator.generateKey();
		return secretKey.getEncoded();
	}
	
	/**
	 * 使用 AES 加密算法,對資料進行加密   
	 * @param src    
	 * @param encryptKey
	 * @return
	 * @throws Exception
	 */
	public static byte [] JDK_AES_Encrypt(String src,byte [] encryptKey) throws Exception{
		// 秘鑰的轉換 
		Key key = new SecretKeySpec(encryptKey, "AES");
		
		//資料加密
		Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
		cipher.init(Cipher.ENCRYPT_MODE, key);
		byte [] result = cipher.doFinal(src.getBytes());
		return result;
	}
	
	/**
	 * 使用 AES 加密算法,對資料進行解密   
	 * @param encryptBytes
	 * @param encryptKey
	 * @return
	 * @throws Exception
	 */
	public static String JDK_AES_Decrypt(byte [] encryptBytes ,byte [] encryptKey) throws Exception{
		//key  的轉換 
		Key key = new SecretKeySpec(encryptKey, "AES");
		
		//解密
		Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
		cipher.init(Cipher.DECRYPT_MODE, key);
		String result = new String(cipher.doFinal(encryptBytes));
		return result;
	}
	
	/**
	 *  jdk   AES 生成秘鑰 ,系統生成預設的秘鑰,自定義長度
	 * @return
	 * @throws Exception
	 */
	public static byte [] BC_AES_GetSecretKey() throws Exception{
		Security.addProvider(new BouncyCastleProvider());
		KeyGenerator keyGenerator = KeyGenerator.getInstance("AES","BC");
		keyGenerator.init(128);   // new SecureRandom() 預設長度 
		Key secretKey = keyGenerator.generateKey();
		return secretKey.getEncoded();
	}
	
	/**
	 * bc   AES 生成秘鑰 ,自定義的秘鑰,生成預設的秘鑰長度
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static byte [] BC_AES_GetSecretKey(String key) throws Exception{
		Security.addProvider(new BouncyCastleProvider());
		KeyGenerator keyGenerator = KeyGenerator.getInstance("AES","BC");
		keyGenerator.init(128,new SecureRandom(key.getBytes()));
		Key secretKey = keyGenerator.generateKey();
		return secretKey.getEncoded();
	}
	
	/**
	 * bc   使用 AES 加密算法,對資料進行加密   
	 * @param src    
	 * @param encryptKey
	 * @return
	 * @throws Exception
	 */
	public static byte [] BC_AES_Encrypt(String src,byte [] encryptKey) throws Exception{
		// 秘鑰的轉換 
		Key key = new SecretKeySpec(encryptKey, "AES");
		
		//資料加密
		Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
		cipher.init(Cipher.ENCRYPT_MODE, key);
		byte [] result = cipher.doFinal(src.getBytes());
		return result;
	}
	
	/**
	 * bc  使用 AES 加密算法,對資料進行解密   
	 * @param encryptBytes
	 * @param encryptKey
	 * @return
	 * @throws Exception
	 */
	public static String BC_AES_Decrypt(byte [] encryptBytes ,byte [] encryptKey) throws Exception{
		//key  的轉換 
		Key key = new SecretKeySpec(encryptKey, "AES");
		
		//解密
		Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
		cipher.init(Cipher.DECRYPT_MODE, key);
		String result = new String(cipher.doFinal(encryptBytes));
		return result;
	}