/**
*
*/
package security;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
/**
* DESC: 对称加密
* <p>
* 仅作学习交流用途,严禁用作商业用途。版权所有,伪版必究。
*
* @Copyright YangFei
* </p>
* @author yfei Date:2013-8-28
*/
public class SymmetricEncryption {
/**
* mark as DES.
*/
private static final String ALGORITHM = "DES";
/**
* DEFAULT password.
*/
private static String defaultStrKey = "yangfei";
/**
* 加密器.
*/
private Cipher decryptCipher = Cipher.getInstance(ALGORITHM);
/**
* 解密器.
*/
private Cipher encryptCipher = Cipher.getInstance(ALGORITHM);
/**
* construct without parameter.
*
* @throws Exception
* the exception
*/
public SymmetricEncryption() throws Exception {
// key = DEFAULT_KEY;
this(defaultStrKey);
}
/**
* construct with parameter password.
*
* @param strKey
* the str key
* @throws Exception
* the exception
*/
public SymmetricEncryption(String strKey) throws Exception {
// DES算法要求有一个可信任的随机数源,可以认为是salt(加盐的加密)
SecureRandom sr = new SecureRandom();
// 生成DESKey
SecretKey desKey = generateDESKey(strKey);
// 初始化加密器
encryptCipher.init(Cipher.ENCRYPT_MODE, desKey, sr);
// 初始化解密器
decryptCipher.init(Cipher.DECRYPT_MODE, desKey, sr);
}
/**
* <b>解密二进制数据.</b>
*
* @param source
* the source
* @return the byte[]
*/
public byte[] decrypt(byte[] source) {
byte[] result = null;
try {
result = decryptCipher.doFinal(source);
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
return result;
}
/*
* (non-Javadoc)
*
* @see com.cnpc.pms.base.crypto.ICrypto#decrypt(java.io.InputStream)
*/
/**
* Decrypt.
*
* @param input
* the input
* @return the output stream
*/
public OutputStream decrypto(InputStream input,OutputStream output) {
//OutputStream output = new ByteArrayOutputStream();
CipherInputStream cis = new CipherInputStream(input, decryptCipher);
byte[] buffer = new byte[1024];
int r;
try {
while ((r = cis.read(buffer)) > 0) {
output.write(buffer, 0, r);
}
cis.close();
input.close();
} catch (IOException e) {
e.printStackTrace();
}
return output;
}
/**
* <b>加密二进制数据.</b>
*
* @param source
* the source
* @return the byte[]
*/
public byte[] encrypt(byte[] source) {
byte[] result = null;
try {
result = encryptCipher.doFinal(source);
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
return result;
}
/**
* Encrypt.
*
* @param input
* the input
* @return the output stream
*/
public OutputStream encrypto(InputStream input,OutputStream output) {
//OutputStream output = new ByteArrayOutputStream();
CipherInputStream cis = new CipherInputStream(input, encryptCipher);
byte[] buffer = new byte[1024];
int r;
try {
while ((r = cis.read(buffer)) > 0) {
output.write(buffer, 0, r);
}
cis.close();
input.close();
} catch (IOException e) {
e.printStackTrace();
}
return output;
}
/**
* <b>transfer byte[8] to SecretKey.</b>
*
* @param strKey
* the str key
* @return the secret key
* @throws InvalidKeyException
* the invalid key exception
* @throws NoSuchAlgorithmException
* the no such algorithm exception
* @throws InvalidKeySpecException
* the invalid key spec exception
* @throws UnsupportedEncodingException
*/
private final SecretKey generateDESKey(String strKey)
throws InvalidKeyException, NoSuchAlgorithmException,
InvalidKeySpecException, UnsupportedEncodingException {
byte[] byteKey = this.getByteKey(strKey);
BigInteger bigInteger = new BigInteger(1,byteKey);
System.out.println("the secrity md5 key is == "+bigInteger.toString(16));
// get DESKey.
DESKeySpec dks = null;
SecretKeyFactory keyFactory = null; // key Factory
SecretKey secretKey = null; // DESKey
// 从原始密匙数据创建DESKeySpec对象
dks = new DESKeySpec(byteKey);
// 创建一个密匙工厂,然后用它把DESKeySpec转换成一个SecretKey对象
keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
secretKey = keyFactory.generateSecret(dks);
return secretKey;
}
/**
* <b>transfer password to byte[8]..</b> byte[]
*
* @param strKey
* the str key
* @return the byte key
* @throws NoSuchAlgorithmException
*/
private final byte[] getByteKey(final String strKey) throws NoSuchAlgorithmException {
// transfer password to byte[8].
MessageDigest md = MessageDigest.getInstance("MD5");
return md.digest(strKey.getBytes());
}
/**
* @param args
*
*/
public static void main(String[] args) {
try {
SymmetricEncryption clazz = new SymmetricEncryption();
InputStream input = new FileInputStream(new File(
"testData/test.docx"));
OutputStream out = new FileOutputStream(new File(
"testData/test_en.docx"));
clazz.encrypto(input, out);
input.close();
out.close();
InputStream input2 = new FileInputStream(new File(
"testData/test_en.docx"));
OutputStream out2 = new FileOutputStream(new File(
"testData/test_de.docx"));
clazz.decrypto(input2, out2);
input2.close();
out2.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
对称算法:A用一个密钥对一个文件加密,而B读取这个文件的话,则须要和A一样的密钥,双方共享一个私钥(而在web环境下,私钥在传递时简单被侦听):
运用私钥加密的话,最先须要一个密钥,可用javax.crypto.KeyGenerator产生一个密钥(java.security.Key), 然后传递给一个加密工具(javax.crypto.Cipher),该工具再运用相应的算法来执行 加密,首要对称算法有:DES(实际密钥只用到56 位),AES(支持三种密钥长度:128、192、256位),通常最先
128位,其他的还有DESede等,jdk1.5种也提供了对对称算法的支持,