import java.security.Security;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
public class SIEncryptUtil {
private String characterEncoding = "ASCII"; // 用来加密密码
private Cipher encryptCipher;
private Cipher decryptCipher;
private BASE64Encoder base64Encoder = new BASE64Encoder();
private BASE64Decoder base64Decoder = new BASE64Decoder();
static SIEncryptUtil sie = null;
// The DES EDE Key - any 24 bytes will do though beware of weak
// keys.
// This could be read from a file. DES的密钥
final static byte[] DESedeKeyBytes = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x01,
0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, };
// IV For CBC mode 算法参数描述
// Again, could be read from a file.
final static byte[] ivBytes = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
0x07 };
/**
* 构造函数 使用DES加密算法
*
* @param keyBytes
* @param ivBytes
* @throws Exception
*/
public SIEncryptUtil(byte[] keyBytes, byte[] ivBytes) throws Exception {
// 构造函数,确保使用的是SunJCE
Security.addProvider(new com.sun.crypto.provider.SunJCE());
SecretKey key = new SecretKeySpec(keyBytes, "DESede");
IvParameterSpec iv = new IvParameterSpec(ivBytes);
this.encryptCipher = Cipher.getInstance("DESede/CBC/PKCS5Padding",
"SunJCE");
this.encryptCipher.init(javax.crypto.Cipher.ENCRYPT_MODE, key, iv);
this.decryptCipher = Cipher.getInstance("DESede/CBC/PKCS5Padding",
"SunJCE");
this.decryptCipher.init(javax.crypto.Cipher.DECRYPT_MODE, key, iv);
}
/**
* 加密字符串 必须用相同的key
*
* @param password
* 要加密的字符串
* @return 返回密文
* @throws Exception
*/
synchronized public String encrypt(String password) throws Exception {
byte[] passwordBytes = password.getBytes();
byte[] encryptedPasswordBytes = this.encryptCipher
.doFinal(passwordBytes);
String encodedEncryptedPassword = this.base64Encoder
.encode(encryptedPasswordBytes);
return encodedEncryptedPassword;
}
/**
* 解密字符串 必须用相同的key
*
* @param encodedEncryptedPassword
* 要解密的密文
* @return 明文
* @throws Exception
*/
synchronized public String decrypt(String encodedEncryptedPassword)
throws Exception {
byte[] encryptedPasswordBytes = this.base64Decoder
.decodeBuffer(encodedEncryptedPassword);
byte[] passwordBytes = this.decryptCipher
.doFinal(encryptedPasswordBytes);
String recoveredPassword = new String(passwordBytes);
return recoveredPassword;
}
/**
* 加密字符串,适合用于加密密码 必须用相同的key
*
* @param password
* 要加密的字符串
* @return 返回密文
* @throws Exception
*/
synchronized public String encryptASCII(String password) throws Exception {
// 判断是否是ASCII模式
if (!password.matches("[ -~]{6,}"))
throw new IllegalArgumentException("String must be ASCII mode.");
byte[] passwordBytes = password.getBytes(characterEncoding);
byte[] encryptedPasswordBytes = this.encryptCipher
.doFinal(passwordBytes);
String encodedEncryptedPassword = this.base64Encoder
.encode(encryptedPasswordBytes);
return encodedEncryptedPassword;
}
/**
* 解密字符串 必须用相同的key
*
* @param encodedEncryptedPassword
* 要解密的密文
* @return 明文
* @throws Exception
*/
synchronized public String decryptASCII(String encodedEncryptedPassword)
throws Exception {
byte[] encryptedPasswordBytes = this.base64Decoder
.decodeBuffer(encodedEncryptedPassword);
byte[] passwordBytes = this.decryptCipher
.doFinal(encryptedPasswordBytes);
String recoveredPassword = new String(passwordBytes, characterEncoding);
return recoveredPassword;
}
/**
* 实例
*
* @return
* @throws Exception
*/
public static SIEncryptUtil getInstance() throws Exception {
if (sie == null) {
sie = new SIEncryptUtil(DESedeKeyBytes, ivBytes);
return sie;
} else {
return sie;
}
}
// Simple test
public static void main(String[] args) {
try {
String password = (args.length == 0) ? "The quick brown fox jumps over the 测试。lazy lao1."
: args[0];
System.out.println("要加密的密码为:..................[" + password
+ "]");
String encodedEncryptedPassword = SIEncryptUtil.getInstance()
.encrypt(password);
System.out.println("加密后的密码为:..................["
+ encodedEncryptedPassword + "]");
String recoveredPassword = SIEncryptUtil.getInstance().decrypt(
encodedEncryptedPassword);
System.out.println("解密后的密码为:..................["
+ recoveredPassword + "]");
} catch (Exception e) {
e.printStackTrace(System.out);
}
}
}