随着对称密码的发展,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)); }