对称加解密算法AES +加解密模式CBC+ 填充模式PKCS5Padding + 128位加解密
1.对称加密: 加密者和解密者用的是同一串秘钥
2.AES有四种加解密模式:CBC、EBC、CFB、OFB 。CBC模式下,加密时,是对明文进行分组加密的,每组大小一致,到 最后 一组时,可能长度不够,这个时候就需要填充到一样长度,就有了下面的填充模式。
3.有两种填充模式:PKCS5Padding、PKCS7Padding 。这两种填充模式填充规则一样,区别在于,分组时,每组约定大小不一样。PKCS5Padding要求块(block)的大小是8位,PKCS7Padding则没有明确,范围在1-255之间
4.秘钥的长度,128位即128bit,AES的秘钥长度一般有:128bit、192bit、256bit。java 中,秘钥里的一个字符是一个字节(1byte),1byte=8bit。一个128位的秘钥,即由16个字符组成,如:"aigov1266aba186k"
代码:
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
import java.security.SecureRandom;
import java.util.Base64;
public class Test {
private static SecureRandom random = new SecureRandom();
//加解密模式CBC + 填充模式PKCS5Padding + 128位加解密
public static void main(String[] args) throws UnsupportedEncodingException, DecoderException {
//生成随机_iv,加解密模式-CBC :使用CBC模式,需要一个向量,增加算法的强度
byte[] bytes = new byte[16];
random.nextBytes(bytes);
String resultIv = new String(Hex.encodeHex(bytes));
System.out.println(" iv : = "+resultIv);
//加密字符串
String str ="age=15AppID=98233030iv=1234567890123456name=316314643131654secret=3d1f3d1f";
byte[] strArr = str.getBytes("UTF-8");
//双方约定secret
String secret = "3dd81e9q3f8c8t4h5s9v2e3t6a8r2cd6";
//iv向量
String iv = "9406238369428fe3c305c9195f4a6f5a";
//十六进制字符串 --> 字节数组
byte[] keyArr = Hex.decodeHex(secret.toCharArray());
byte[] ivArr = Hex.decodeHex(iv.toCharArray());
//加密
byte[] arrByte = null;
try {
SecretKey secretKey = new SecretKeySpec(keyArr, "AES");
IvParameterSpec ivSpec = new IvParameterSpec(ivArr);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(1, secretKey, ivSpec);
arrByte = cipher.doFinal(strArr);
//Base64加密,也可转16进制字符串
/*Base64.Encoder encoder = Base64.getEncoder();
System.out.println("----"+encoder.encodeToString(arrByte));*/
} catch (GeneralSecurityException e) {
}
System.out.println("arrByte = "+arrByte.length);
//字节数组 --> 十六进制字符串
String result = new String(Hex.encodeHex(arrByte));
System.out.println("result = "+result);
}
}