AES加密解密工具类
按:以下内容涉及传统的AES加密解密方法,熟悉它的请不要浪费宝贵时间。
如果用Base64进行加密解密是不安全的,因为这种方式的方法和密钥(字符映射表)都是公开的,对此熟悉的人如果看到一串字符后面带一些等号,很容易想到是Base64进行加密。因此,我们必须采取一些更安全的加密解密方式,AES就是其一。
在使用AES进行加密解密之前,需要到Sun的官方网站上下载一个权限文件:jce_policy,目前它的下载网址是: http://www.oracle.com/technetwork/java/javase/downloads/index.html ,找到“Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 6”后点击按钮下载,得到下载文件后解开,然后将其中的local_policy.jar和US_export_policy.jar拷贝到你的JAVA_HOME\jre\lib\security和JRE_HOME\lib\security两个目录下。如果没有这一步骤,进行加密解密的时候会产生java.security.InvalidKeyException异常。
接下来就是代码了:
上面代码中值得注意的是,加密后的结果不能直接变成String形式,因为这会导致解密的不可行(解密抛出javax.crypto.IllegalBlockSizeException异常)。如果要使用其他的Key,可以单独执行一下initKeyHex()函数,将输出结果置换掉静态变量Key的值即可。
这样,在AES的帮助下,我们实现了比较安全的加密,破解者知道方法AES,但不知道密钥的话,解密会很困难。但是,话说回来,java程序被反编译很容易,别有用心的人还是可以看到密钥,但我们还是可以用公钥加密私钥解密的方式来对付,这个以后有空再说。
好了,感谢您看到这里。
如果用Base64进行加密解密是不安全的,因为这种方式的方法和密钥(字符映射表)都是公开的,对此熟悉的人如果看到一串字符后面带一些等号,很容易想到是Base64进行加密。因此,我们必须采取一些更安全的加密解密方式,AES就是其一。
在使用AES进行加密解密之前,需要到Sun的官方网站上下载一个权限文件:jce_policy,目前它的下载网址是: http://www.oracle.com/technetwork/java/javase/downloads/index.html ,找到“Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 6”后点击按钮下载,得到下载文件后解开,然后将其中的local_policy.jar和US_export_policy.jar拷贝到你的JAVA_HOME\jre\lib\security和JRE_HOME\lib\security两个目录下。如果没有这一步骤,进行加密解密的时候会产生java.security.InvalidKeyException异常。
接下来就是代码了:
package
com.heyang.util;
import java.security.Key;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Hex;
/**
* AES算法加密解密实用工具类
* 说明:
* 作者:何杨([email protected])
* 创建时间:2010-11-29 上午11:19:11
* 修改时间:2010-11-29 上午11:19:11
*/
public class AESSecurityUtil{
// 加密方法
private static final String Algorithm = " AES " ;
// 进行加密解密的密钥
private static final String Key = " 03a53dfc257fe1b0996626a5e2e2210692936bd16cc60f37211cbeef9353e268 " ;
/**
* 取得解密后的字符串
*
* 说明:
* @param encryptArr
* @return
* 创建时间:2010-12-1 下午03:33:31
*/
public static String getDecryptString( byte [] encryptArr){
try {
Cipher cp = Cipher.getInstance(Algorithm);
cp.init(Cipher.DECRYPT_MODE, getKey());
byte [] arr = cp.doFinal(encryptArr);
return new String(arr);
}
catch (Exception ex){
System.out.println( " 无法进行解密,原因是 " + ex.getMessage());
return null ;
}
}
/**
* 取得加密后的字节数组
*
* 说明:
* @param originalString
* @return
* 创建时间:2010-12-1 下午03:33:49
*/
public static byte [] getEncryptByteArray(String originalString){
try {
Cipher cp = Cipher.getInstance(Algorithm);
cp.init(Cipher.ENCRYPT_MODE, getKey());
return cp.doFinal(originalString.getBytes());
}
catch (Exception ex){
System.out.println( " 无法进行加密,原因是 " + ex.getMessage());
return null ;
}
}
/**
* 取得密钥数组
*
* 说明:
* @return
* @throws Exception
* 创建时间:2010-12-1 下午03:31:08
*/
private static byte [] initKey() throws Exception{
KeyGenerator kg = KeyGenerator.getInstance(Algorithm);
kg.init( 256 );
SecretKey sk = kg.generateKey();
return sk.getEncoded();
}
/**
* 取得字符串形式的密钥
*
* 说明:
* @return
* @throws Exception
* 创建时间:2010-12-1 下午03:31:36
*/
public static String initKeyHex() throws Exception{
return new String(Hex.encodeHex(initKey()));
}
/**
* 取得密钥
*
* 说明:
* @return
* @throws Exception
* 创建时间:2010-12-1 下午03:33:17
*/
private static Key getKey() throws Exception{
byte [] arr = Hex.decodeHex(Key.toCharArray());
return new SecretKeySpec(arr,Algorithm);
}
public static void main(String[] args) throws Exception{
// System.out.println(initKeyHex());
String str = " Hello!World 你好!世界。 " ;
byte [] arr = AESSecurityUtil.getEncryptByteArray(str);
System.out.print( " AES加密后的结果为: " );
for ( byte b:arr){
System.out.print(b);
}
System.out.println();
String str1 = AESSecurityUtil.getDecryptString(arr);
System.out.println( " AES解密后的字符串为: " + str1);
}
}
测试输出如下:
import java.security.Key;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Hex;
/**
* AES算法加密解密实用工具类
* 说明:
* 作者:何杨([email protected])
* 创建时间:2010-11-29 上午11:19:11
* 修改时间:2010-11-29 上午11:19:11
*/
public class AESSecurityUtil{
// 加密方法
private static final String Algorithm = " AES " ;
// 进行加密解密的密钥
private static final String Key = " 03a53dfc257fe1b0996626a5e2e2210692936bd16cc60f37211cbeef9353e268 " ;
/**
* 取得解密后的字符串
*
* 说明:
* @param encryptArr
* @return
* 创建时间:2010-12-1 下午03:33:31
*/
public static String getDecryptString( byte [] encryptArr){
try {
Cipher cp = Cipher.getInstance(Algorithm);
cp.init(Cipher.DECRYPT_MODE, getKey());
byte [] arr = cp.doFinal(encryptArr);
return new String(arr);
}
catch (Exception ex){
System.out.println( " 无法进行解密,原因是 " + ex.getMessage());
return null ;
}
}
/**
* 取得加密后的字节数组
*
* 说明:
* @param originalString
* @return
* 创建时间:2010-12-1 下午03:33:49
*/
public static byte [] getEncryptByteArray(String originalString){
try {
Cipher cp = Cipher.getInstance(Algorithm);
cp.init(Cipher.ENCRYPT_MODE, getKey());
return cp.doFinal(originalString.getBytes());
}
catch (Exception ex){
System.out.println( " 无法进行加密,原因是 " + ex.getMessage());
return null ;
}
}
/**
* 取得密钥数组
*
* 说明:
* @return
* @throws Exception
* 创建时间:2010-12-1 下午03:31:08
*/
private static byte [] initKey() throws Exception{
KeyGenerator kg = KeyGenerator.getInstance(Algorithm);
kg.init( 256 );
SecretKey sk = kg.generateKey();
return sk.getEncoded();
}
/**
* 取得字符串形式的密钥
*
* 说明:
* @return
* @throws Exception
* 创建时间:2010-12-1 下午03:31:36
*/
public static String initKeyHex() throws Exception{
return new String(Hex.encodeHex(initKey()));
}
/**
* 取得密钥
*
* 说明:
* @return
* @throws Exception
* 创建时间:2010-12-1 下午03:33:17
*/
private static Key getKey() throws Exception{
byte [] arr = Hex.decodeHex(Key.toCharArray());
return new SecretKeySpec(arr,Algorithm);
}
public static void main(String[] args) throws Exception{
// System.out.println(initKeyHex());
String str = " Hello!World 你好!世界。 " ;
byte [] arr = AESSecurityUtil.getEncryptByteArray(str);
System.out.print( " AES加密后的结果为: " );
for ( byte b:arr){
System.out.print(b);
}
System.out.println();
String str1 = AESSecurityUtil.getDecryptString(arr);
System.out.println( " AES解密后的字符串为: " + str1);
}
}
AES加密后的结果为:
833522115
-
115
-
6373
-
10
-
940
-
110
-
93
-
87736
-
561
-
1083427
-
99
-
6
-
6218
-
4104108
-
1031216395
-
92
AES解密后的字符串为:Hello ! World 你好!世界。
AES解密后的字符串为:Hello ! World 你好!世界。
上面代码中值得注意的是,加密后的结果不能直接变成String形式,因为这会导致解密的不可行(解密抛出javax.crypto.IllegalBlockSizeException异常)。如果要使用其他的Key,可以单独执行一下initKeyHex()函数,将输出结果置换掉静态变量Key的值即可。
这样,在AES的帮助下,我们实现了比较安全的加密,破解者知道方法AES,但不知道密钥的话,解密会很困难。但是,话说回来,java程序被反编译很容易,别有用心的人还是可以看到密钥,但我们还是可以用公钥加密私钥解密的方式来对付,这个以后有空再说。
好了,感谢您看到这里。