AES加密记

在webservice开发时进行传输内容的AES加密要求:

 

密钥:密钥使用192比特(24字节),如果小于 192比特,末尾用 0x00补齐

明文:加密明文为 16字节倍数(128比特)无法被16整除的情况加密数据内容采用PKCS7Padding 方式填充(即长度以16字节切分,不能被 16 整除的末尾部分,根据长度不足 8 字节的部分,填充 ”0x01”—“0x10”,如不足1 字节,则填充 1 "0x01",如不足2 字节,则填充 2 "0x02”,以此类推,如整除,则填充 16 个“0x10")

 

代码如下:

 

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.util.Arrays;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

/**
 * AES采用192位密钥(共16,24,32字节三种), jdk默认只支持128位密钥
 * 其他位数需更换 jdk安装路径中jre/lib/security下的local_policy.jar,US_export_policy.jar
 *
 * @author tanch
 * */
public class SecretTransUtil {
      
    public static final int SIZE = 24; 
    public final static String AES = "AES";
    
 
      /**
       * AES加密
       *
       * @param content 需要加密的内容
       * @param password 解密密钥
       * @return
       */
       public String encryptAES(String content, String password) {
             try {
                   byte[] compBefore = password.getBytes();
                   byte[] compAfter = Arrays.copyOf(compBefore, 24);
                  SecretKeySpec key = new SecretKeySpec(compAfter, AES);
                  Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); // 创建密码器
                   byte[] byteContent = content.getBytes("utf-8" );
                  cipher.init(Cipher. ENCRYPT_MODE, key);// 初始化
                   byte[] encryptResult = cipher.doFinal(byteContent);
                  String result = parseByte2HexStr(encryptResult);
                   return result; // 加密
            } catch (Exception e) {
                  e.printStackTrace();
            }
             return null ;
      }
      
    /**AES解密
     * @param content  待解密内容
     * @param password 解密密钥
     * @return
     */
    public synchronized String decryptAES(String content, String password) {
             try {
                   byte[] compBefore = password.getBytes();
                   byte[] compAfter = Arrays.copyOf(compBefore, 24);
                  SecretKeySpec key = new SecretKeySpec(compAfter, AES);
                  Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); // 创建密码器
                  cipher.init(Cipher. DECRYPT_MODE, key);// 初始化
                   byte[] decryptResult = cipher.doFinal(parseHexStr2Byte(content));
                   return new String(decryptResult);
            } catch (Exception e) {
                   return null ;
            }
           
    }
   
    /**将二进制转换成16进制
     * @param buf
     * @return
     */
    public 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
     */
    public  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;
    }
   

补充知识:二进制与十六进制的转化

1   首先需要记住8,4,2,1四个数字分别代表:1000,0100,0010,0001

     十六进制的最高F为15,也就是8+4+2+1,4个bit可以表示一位十六进制字符

     java中byte占8bit,即byte可以容纳两个十六进制字符

 

2  buf[i] & 0xFF:

    Integer.toHexString的参数是int,如果不进行&0xff,由于java的二进制采用的是补码形式,

    那么当一个byte会转换成int时, 由于int是32位,而byte只有8位这时会进行补位。

 

   例如:补码11111111的十进制数为-1转换为int时变为11111111111111111111111111111111

             即0xffffffff这种补位就会造成误差。 和0xff相与后,高24比特就会被清0了,结果就对了。

 

    

补充知识来自:http://franksinger.iteye.com/blog/614540

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值