import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.SecretKeySpec;
import com.lenovo.lps.log.Log;
/**
* AESUtil调用工具类
*/
public class AESUtil {
/*算法/模式/填充 16字节加密后数据长度 不满16字节加密后长度
AES/CBC/NoPadding 16 不支持
AES/CBC/PKCS5Padding 32 16
AES/CBC/ISO10126Padding 32 16
AES/CFB/NoPadding 16 原始数据长度
AES/CFB/PKCS5Padding 32 16
AES/CFB/ISO10126Padding 32 16
AES/ECB/NoPadding 16 不支持
AES/ECB/PKCS5Padding 32 16
AES/ECB/ISO10126Padding 32 16
AES/OFB/NoPadding 16 原始数据长度
AES/OFB/PKCS5Padding 32 16
AES/OFB/ISO10126Padding 32 16
AES/PCBC/NoPadding 16 不支持
AES/PCBC/PKCS5Padding 32 16
AES/PCBC/ISO10126Padding 32 16
测试:AES/ECB/PKCS5Padding AES/ECB/NoPadding AES/OFB/NoPadding
*/
private static String CIPHER_ALGORITHM="AES/ECB/PKCS5Padding";
//private static String CIPHER_ALGORITHM="AES/ECB/NoPadding";
//private static String CIPHER_ALGORITHM="AES/OFB/NoPadding";
private static Log log = Log.getInstance(AESUtil.class);
private static final int HMAC_NLENGTH = 16;
public static final byte[] HEX_CHAR_TABLE = { (byte) '0', (byte) '1',
(byte) '2', (byte) '3', (byte) '4', (byte) '5', (byte) '6',
(byte) '7', (byte) '8', (byte) '9', (byte) 'A', (byte) 'B',
(byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F' };
public static String toHexString(byte[] raw)
throws UnsupportedEncodingException {
byte[] hex = new byte[2 * raw.length];
int index = 0;
for (byte b : raw) {
int v = b & 0xFF;
hex[index++] = HEX_CHAR_TABLE[v >>> 4];
hex[index++] = HEX_CHAR_TABLE[v & 0xF];
}
return new String(hex, "ASCII");
}
public static int hexChar2int(byte hexChar){
if( hexChar<HEX_CHAR_TABLE[10] ){
return hexChar-HEX_CHAR_TABLE[0];
}else{
return hexChar-HEX_CHAR_TABLE[10]+10;
}
}
public static byte[] hexString2Byte(String s){
byte[] raw = s.getBytes();
byte[] hex = new byte[ raw.length/2];
for (int i=0;i<hex.length;i++) {
int leftBit4 = hexChar2int(raw[2*i]) << 4;
hex[i] = (byte)( leftBit4 | hexChar2int(raw[2*i+1]) );
}
return hex;
}
private static final String SHA1_PRNG = "SHA1PRNG";
// Default here is 128-bits of random goodness.
//private static final int DEFAULT_RANDOM_SIZE = 128;
// This isn't thread safe but we probably don't really care
// since all we're doing is reading a bunch of random numbers
// out of the generator.
private static final SecureRandom sRandom__;
static {
try {
sRandom__ = SecureRandom.getInstance( SHA1_PRNG );
} catch ( NoSuchAlgorithmException e ) {
throw new Error(e);
}
}
/** * Get the number of next random bits in this SecureRandom
* * generators' sequence.
* * @param size how many random bits you want
* * @return
* */
public static byte [] getNextSecureRandom ( int bytecount )
{
// Usually 64-bits of randomness, 8 bytes
final byte [] bytes = new byte[ bytecount ];
// Get the next 64 random bits. Forces SecureRandom
// to seed itself before returning the bytes.
sRandom__.nextBytes(bytes);
return bytes;
}
public static SecretKey createKey(String algrithm)
throws NoSuchAlgorithmException {
KeyGenerator keyGen = null;
SecretKey key = null;
keyGen = KeyGenerator.getInstance(algrithm);
if (keyGen != null){
key = keyGen.generateKey();
}
return key;
}
public static byte[] HMACSHA256_128(Key keySpec, byte[] src) {
return HMACSHA256_128(keySpec, src, HMAC_NLENGTH);
}
public static byte[] HMACSHA256_128(Key keySpec, byte[] src,int nLength) {
javax.crypto.Mac mac = null;
// SecretKey key=new SceretKey();
byte[] res = null;
try {
mac = javax.crypto.Mac.getInstance("HmacSHA256");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
try {
mac.init(keySpec);
} catch (InvalidKeyException e) {
e.printStackTrace();
}
// get 32 bytes HMACSHA256 result.
res = mac.doFinal(src);
// now truncate into nLength bytes HMACSHA256-128 result.
byte[] ret = new byte[nLength];
for (int i = 0; i < nLength; i++)
ret[i] = res[i];
return ret;
}
public static byte[] encryptAES(Key keySpec, byte[] src) {
javax.crypto.Cipher cip = null;
// SecretKey key=new SceretKey();
byte[] res = null;
try {
cip = javax.crypto.Cipher.getInstance(CIPHER_ALGORITHM);
cip.init(javax.crypto.Cipher.ENCRYPT_MODE, keySpec);
res = cip.doFinal(src);
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
return res;
}
public static byte[] decryptAES(Key keySpec, byte[] src) throws CryptogramException{
javax.crypto.Cipher cip = null;
// SecretKey key=new SceretKey();
byte[] res = null;
try {
cip = javax.crypto.Cipher.getInstance(CIPHER_ALGORITHM);
cip.init(javax.crypto.Cipher.DECRYPT_MODE, keySpec);
res = cip.doFinal(src);
} catch (NoSuchPaddingException e) {
throw new CryptogramException("NoSuchPaddingException");
} catch (NoSuchAlgorithmException e) {
throw new CryptogramException("InvalidKeyException");
} catch (InvalidKeyException e) {
throw new CryptogramException("CryptogramException");
} catch (IllegalBlockSizeException e) {
throw new CryptogramException("IllegalBlockSizeException");
} catch (BadPaddingException e) {
throw new CryptogramException("BadPaddingException");
}
return res;
}
public static SecretKey createHMACKey(){
try {
return AESUtil.createKey("HmacSHA256");
}catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return null;
}
}
public static String getKeyValue( SecretKey keya ){
String keys=null;
try {
byte[] ksba= keya.getEncoded();
keys= AESUtil.toHexString(ksba);
return keys;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return keys;
}
public static SecretKey createAESKey(){
try {
return AESUtil.createKey("AES");
}catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return null;
}
}
/**
* 转换AES加密Key值
* @param KeyStr
* @return
* @throws Exception
*/
public static Key generateSecretKey(String KeyStr) throws Exception {
byte[] input =hexString2Byte(KeyStr);
//byte[] input = Hex.decode(KeyStr);
//byte[] raw = skey.getEncoded();
//byte[] key = KeyStr.getBytes("utf-8");
SecretKeySpec skeySpec = new SecretKeySpec(input, "AES");
SecretKeyFactory KeyFactory = SecretKeyFactory.getInstance("AES");
return ((Key) (KeyFactory
.generateSecret(((java.security.spec.KeySpec) (skeySpec)))));
}
public static SecretKey retrieveHMACKey(String keyValue){
try {
SecretKey keya = new SecretKeySpec(hexString2Byte(keyValue),"HmacSHA256");
//get secret key.
return keya ;
} catch (IllegalArgumentException e) {
log.error("retrieveHMACKey error, keyValue: " + keyValue, e );
if( log.isDebugEnabled() ){
e.printStackTrace();
}
return null;
}
}
public static SecretKey retrieveAESKey(String keyValue){
try {
SecretKey keya = new SecretKeySpec(hexString2Byte(keyValue),"AES");
//get secret key.
return keya ;
} catch (IllegalArgumentException e) {
log.error("retrieveAESKey error, keyValue: " + keyValue, e );
if( log.isDebugEnabled() ){
e.printStackTrace();
}
return null;
}
}
public static SecretKey retrieveKey(String algrithm,String keyValue){
try {
SecretKey keya = new SecretKeySpec(hexString2Byte(keyValue),algrithm);
//get secret key.
return keya ;
} catch (IllegalArgumentException e) {
log.error("retrieveAESKey error, keyValue: " + keyValue, e );
if( log.isDebugEnabled() ){
e.printStackTrace();
}
return null;
}
}
public static String createAEScommonKey(){
SecretKey key = createAESKey();
String kv = getKeyValue( key );
System.out.println("AESKey:" + kv );
if(!kv.equals( getKeyValue(retrieveAESKey(kv)))){
System.out.println("wrong !" );
}
return kv;
}
public static String createGlobalHMACKey(){
SecretKey key = createHMACKey();
String kv = getKeyValue( key );
System.out.println("HMACKey:" + kv );
if(!kv.equals( getKeyValue(retrieveHMACKey(kv)))){
System.out.println("wrong !" );
}
return kv;
}
public static void main(String[] args){
createAEScommonKey();
//createGlobalHMACKey();
// long startTime=System.nanoTime();
//
// int testMode=0;
// int k=65535;
// int intValue_max=0;
// while(true){
// if(testMode==0){
// k=k+1;
// intValue_max=k;
// }else{
// intValue_max=k++;
// }
// if(k<0)break;
// }
// System.out.println("k :"+ k);
// System.out.println("intValue_max :"+ intValue_max);
// System.out.print("COST:"+(System.nanoTime()-startTime));
//
// for( int i=0;i<32;i++ ){
// SecretKey key = createHMACKey();
// String kv = getKeyValue( key );
// System.out.println("HMACKey:" + kv );
// //SecretKey key2 = retireHMACKey(kv);
// if(!kv.equals( getKeyValue(retrieveHMACKey(kv)))){
// System.out.println("wrong !" );
// }
// }
// byte[] bb = hexString2Byte("B125A533104656CCE8F6B4714231A3C2");
/*byte[] bData = new byte[]{ (byte)33 };
String s = ">";
try{
String sHex = toHexString(s.getBytes());
String Hex33 = toHexString(bData);
System.out.println("test hex : " + s + " --hex--> " + sHex + " -unhex-> " + new String(hexString2Byte(sHex)) );
System.out.println("test hex : " + 33 + " --hex--> " + Hex33 + " -unhex-> " + new String(hexString2Byte(Hex33)) );
}catch(Exception ee ){
ee.printStackTrace();
}
for( int i=0;i<32;i++ ){
SecretKey key = createHMACKey();
String kv = getKeyValue( key );
System.out.println("HMACKey:" + kv );
//SecretKey key2 = retireHMACKey(kv);
if(!kv.equals( getKeyValue(retrieveHMACKey(kv)))){
System.out.println("wrong !" );
}
}
for( int i=0;i<8;i++ ){
SecretKey key = createAESKey();
String kv = getKeyValue( key );
System.out.println("AESKey:" + kv );
//SecretKey key2 = retireHMACKey(kv);
if(!kv.equals( getKeyValue(retrieveAESKey(kv)))){
System.out.println("wrong !" );
}
}*/
}
}