AES 代码实现

来源:互联网 发布:数据港 编辑:程序博客网 时间:2024/06/11 13:09

1 分组加密
首先了解下什么是分组加密:分组密码是将明文消息编码表示后的数字(简称明文数字)序列,划分成长度为n的组(可看成长度为n的矢量),每组分别在密钥的控制下变换成等长的输出数字(简称密文数字)序列。

这里写图片描述
3 ECB的加密方式
http://zh.wikipedia.org/wiki/%E5%9D%97%E5%AF%86%E7%A0%81%E7%9A%84%E5%B7%A5%E4%BD%9C%E6%A8%A1%E5%BC%8F

电码本模式:这种模式是将整个明文分成若干段相同的小段,然后对每一小段进行加密
这里写图片描述
将明文的各个分组独立的使用相同的密钥进行加密,这种方式加密时各分组的加密独立进行互不干涉,因而可并行进行。同样因为各分组独立加密的缘故,相同的明文分组加密之后具有相同的密文。该模式容易暴露明文分组的统计规律和结构特征。不能防范替换攻击。

优点:

1.简单;

2.有利于并行计算;

3.误差不会被传送;

缺点:

1.不能隐藏明文的模式;

2.可能对明文进行主动攻击;

2 CBC加密模式
密码分组链接模式:这种模式是先将明文切分成若干小段,然后每一小段与初始块或者上一段的密文段进行异或运算后,再与密钥进行加密;
这里写图片描述
优点:

1.不容易主动攻击,安全性好于ECB,适合传输长度长的报文,是SSL、IPSec的标准。

缺点:

1.不利于并行计算;

2.误差传递;

3.需要初始化向量IV

3 编程实现

package com.zhy.concurrency.cyclic;import java.security.InvalidAlgorithmParameterException;import java.security.InvalidKeyException;import java.security.NoSuchAlgorithmException;import java.security.SecureRandom;import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.NoSuchPaddingException;import javax.crypto.spec.IvParameterSpec;import javax.crypto.spec.SecretKeySpec;public class AesEncryption {    // 使用CBC加密需要使用添加一个向量    // 此处不符合安全规范:分组密码算法使用到的IV值,必须不可预测;推荐使用安全的随机数    public static void main(String[] args) {              // TODO Auto-generated method stub              String aes_key = "0123456789abcdef";              // 此处密钥硬编码              String strSrc = "0123456789abcdefadmin";              // 数据明文,敏感信息泄露              System.out.println(strSrc);              String encrypt_code = AesEncrypt_test(strSrc, aes_key);              System.out.println(encrypt_code);              String decrypt_code = AesDncrypt_test(encrypt_code, aes_key);              System.out.println(decrypt_code);              // log打印,敏感信息泄露    }    // 使用CBC的加密算法,要求密钥为16byte    public static String AesEncrypt_test(String content, String aes_key) {              try {                       byte[] raw = aes_key.getBytes();                       SecretKeySpec secretkey = new SecretKeySpec(raw, "AES");                       Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");                       SecureRandom random = new SecureRandom();                       byte ivParameter[] = new byte[16];                       random.nextBytes(ivParameter);                       System.out.println(parseByte2HexStr(ivParameter));                       IvParameterSpec ivparam = new IvParameterSpec(ivParameter);                       cipher.init(Cipher.ENCRYPT_MODE, secretkey, ivparam);                       byte[] encrypted = cipher.doFinal(content.getBytes());                       return parseByte2HexStr(ivParameter) + parseByte2HexStr(encrypted);                       //将IV生成的结果附在加密数据前16bytes,每次都使用不同的iv              } catch (InvalidKeyException | NoSuchAlgorithmException                                | NoSuchPaddingException | InvalidAlgorithmParameterException                                | IllegalBlockSizeException | BadPaddingException e) {                       // TODO Auto-generated catch block                       e.printStackTrace();              }              return null;    }    public static String AesDncrypt_test(String content, String aes_key) {              try {                       byte[] raw = aes_key.getBytes();                       SecretKeySpec secretkey = new SecretKeySpec(raw, "AES");                       Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");                       String ivParameter = content.substring(0,32);                  //取前16byte作为cbc解密的iv向量                       System.out.println(ivParameter);                       IvParameterSpec ivparam = new IvParameterSpec(                                          parseHexStr2Byte(ivParameter));                       cipher.init(Cipher.DECRYPT_MODE, secretkey, ivparam);                       byte[] decrypted = cipher.doFinal(parseHexStr2Byte(content.substring(32)));                       return new String(decrypted);              } catch (InvalidKeyException | NoSuchAlgorithmException                                | NoSuchPaddingException | InvalidAlgorithmParameterException                                | IllegalBlockSizeException | BadPaddingException e) {                       // TODO Auto-generated catch block                       e.printStackTrace();              }              return null;    }    /**     * 将2进制转换为16进制     *      * @param hexStr     * @return     */    private 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();    }    /**     * 将16进制转换为二进制     *      * @param hexStr     * @return     */    private 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;}}
0 0
原创粉丝点击