import org.bouncycastle.jce.provider.BouncyCastleProvider;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Security;
import java.util.Arrays;
public class AES {
public static void main(String[] args) throws IOException {
AES aes = new AES();
// 加解密 密钥
// String key = "1234567890qwertyuiopasdfghjklzxc";
// b'\x87\xe9\x11\xfe\x82\xce\x8dS\x08;9\xd2\xbfx\x03\x95\x15\x99\xc2\x02\x9c\xcb\xaa\xd7G\x16\xd8\xae\x157U\xdb'
byte[] keybytes = {(byte)0x87,(byte)0xe9,(byte)0x11,(byte)0xfe,(byte)0x82,(byte)0xce,(byte)0x8d,'S',(byte)0x08,';','9',(byte)0xd2,(byte)0xbf,'x',(byte)0x03,(byte)0x95,(byte)0x15,(byte)0x99,(byte)0xc2,(byte)0x02,(byte)0x9c,(byte)0xcb,(byte)0xaa,(byte)0xd7,'G',(byte)0x16,(byte)0xd8,(byte)0xae,(byte)0x15,'7','U',(byte)0xdb};
// byte[] keybytes = { '1','2','3','4','5','6','7','8','9','0','q','w','e','r','t','y','u','i','o','p','a','s','d','f','g','h','j','k','l','z','x','c' };
// byte[] keybytes = key.getBytes();
byte[] iv = {(byte)0x87,(byte)0xe9,(byte)0x11,(byte)0xfe,(byte)0x82,(byte)0xce,(byte)0x8d,'S',(byte)0x08,';','9',(byte)0xd2,(byte)0xbf,'x',(byte)0x03,(byte)0x95};
//加密字符串
String content = "Hello, 韩- 梅 -梅";
System.out.println("加密前的:" + content);
System.out.println("加密密钥:" + new String(keybytes));
// 加密方法
String enc = aes.encrypt(content.getBytes(), keybytes,iv);
// String encode = new BASE64Encoder().encode(enc);
System.out.println("加密后的内容:" + enc);
// System.out.println("加密后的内容:" + new String(Hex.encode(enc)));
// 解密方法
// byte[] bytes = new BASE64Decoder().decodeBuffer(enc);
String dec = aes.decrypt(enc, keybytes,iv);
System.out.println("解密后的内容:" + new String(dec));
}
/**
*
* @author ngh
*
* AES128 算法
*
* CBC 模式
*
* PKCS7Padding 填充模式
*
* CBC模式需要添加一个参数iv
*
* 介于java 不支持PKCS7Padding,只支持PKCS5Padding 但是PKCS7Padding 和 PKCS5Padding 没有什么区别
* 要实现在java端用PKCS7Padding填充,需要用到bouncycastle组件来实现
*/
// 算法名称
final String KEY_ALGORITHM = "AES";
// 加解密算法/模式/填充方式
final String algorithmStr = "AES/CBC/PKCS7Padding";
//
private Key key;
private Cipher cipher;
boolean isInited = false;
// String ivs = "1234567890qwerty";
// byte[] iv = ivs.getBytes();
// byte[] iv = {'1','2','3','4','5','6','7','8','9','0', 'q', 'w', 'e', 'r', 't', 'y' };
public void init(byte[] keyBytes) {
// 如果密钥不足16位,那么就补足. 这个if 中的内容很重要
int base = 16;
if (keyBytes.length % base != 0) {
int groups = keyBytes.length / base + (keyBytes.length % base != 0 ? 1 : 0);
byte[] temp = new byte[groups * base];
Arrays.fill(temp, (byte) 0);
System.arraycopy(keyBytes, 0, temp, 0, keyBytes.length);
keyBytes = temp;
}
// 初始化
Security.addProvider(new BouncyCastleProvider());
// 转化成JAVA的密钥格式
key = new SecretKeySpec(keyBytes, KEY_ALGORITHM);
try {
// 初始化cipher
cipher = Cipher.getInstance(algorithmStr, "BC");
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchProviderException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 加密方法
*
* @param content
* 要加密的字符串
* @param keyBytes
* 加密密钥
* @return
*/
public String encrypt(byte[] content, byte[] keyBytes,byte[] iv) {
byte[] encryptedText = null;
init(keyBytes);
System.out.println("IV:" + new String(iv));
try {
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
encryptedText = cipher.doFinal(content);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String encode = new BASE64Encoder().encode(encryptedText);
return encode;
}
/**
* 解密方法
*
*
* 要解密的字符串
* @param keyBytes
* 解密密钥
* @return
*/
public String decrypt(String enc, byte[] keyBytes,byte[] iv) throws IOException {
byte[] encryptedData = new BASE64Decoder().decodeBuffer(enc);
byte[] encryptedText = null;
init(keyBytes);
System.out.println("IV:" + new String(iv));
try {
cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
encryptedText = cipher.doFinal(encryptedData);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// String encode = new BASE64Encoder().encode(encryptedText);
String str = new String(encryptedText);
return str;
}
}