1. 程式人生 > >AES對資料進行加密與解密

AES對資料進行加密與解密

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));
}
  

春風如貴客,一到便繁華