java文件加解密算法
java文件加解密
package smart.jrsoft.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.security.MessageDigest;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
public class EncryptUtil {
/**
* 用户MD5不可逆算法对密钥字符串进行加密
*
* @param inStr
* @return
*/
public static String encrypt(String inStr) {
MessageDigest md = null;
String out = null;
try {
md = MessageDigest.getInstance("MD5");
byte[] digest = md.digest(inStr.getBytes());
out = byte2hex(digest);
} catch (Exception e) {
e.printStackTrace();
}
return out;
}
private static String byte2hex(byte[] b) {
String hs = "";
String stmp = "";
for (int n = 0; n < b.length; n++) {
stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
if (stmp.length() == 1) {
hs = hs + "0" + stmp;
} else {
hs = hs + stmp;
}
}
return hs.toUpperCase();
}
/**
* 加密方法 输入:要加密的文件,密钥字符串 输出: 对输入的文件加密后,保存到同一文件夹下增加了".jsmt"扩展名的文件中。
*/
public static int encryptFile(String FileName, String sKey) {
int Rtn = 0;
try {
// 因为密钥须为32位的字符串,故将用户传递的参数用encrypt方法进行处理;
// (由0-F组成,共32个字符,我们将其拆解为2个16位的密码后进行二次加密运算)如:
// AD67EA2F3BE6E5AD D368DFE03120B5DF
sKey = encrypt(sKey);
System.out.println(sKey);
if (sKey.length() != 32) {
Rtn = -1; // sKey is Wrong. //密码长度必须等于32!
return Rtn;
}
byte[] bytK1 = getKeyByStr(sKey.substring(0, 16));
byte[] bytK2 = getKeyByStr(sKey.substring(16, 32));
File fileIn = new File(FileName);
if (!fileIn.exists()) {
Rtn = -2; // 需要加密的文件没有找到。
return Rtn;
}
FileInputStream fis = new FileInputStream(fileIn);
byte[] bytIn = new byte[(int) fileIn.length()];
for (int i = 0; i < fileIn.length(); i++) {
bytIn[i] = (byte) fis.read();
}
// 加密
byte[] bytOut = encryptByDES(encryptByDES(bytIn, bytK1), bytK2);
String fileOut = fileIn.getPath() + ".jsmt";
FileOutputStream fos = new FileOutputStream(fileOut);
for (int i = 0; i < bytOut.length; i++) {
fos.write((int) bytOut[i]);
}
fos.close();
return Rtn;
} catch (Exception e) {
Rtn = -3; // 其他原因导致的加密失败!
return Rtn;
}
}
/**
* 解密函数 输入: 要解密的文件,密钥字符串 输出: 对制定的文件进行解密处理,保存到用户指定的文件中。(注:待解密的文件扩展名必须为:.jsmt)
*/
public static int decryptFile(String CryptFileName, String sKey) {
int Rtn = 0; // 默认的返回值为0,成功!
try {
// 因为密钥须为32位的字符串,故将用户传递的参数用encrypt方法进行处理;
// (由0-F组成,共32个字符,我们将其拆解为2个16位的密码后进行二次解密运算)如:
// AD67EA2F3BE6E5AD D368DFE03120B5DF
sKey = encrypt(sKey);
if (sKey.length() != 32) {
Rtn = -1; // sKey is Wrong. //密码长度必须等于32!
return Rtn;
}
String strPath = CryptFileName;
if (!strPath.substring(strPath.length() - 5).toLowerCase().equals(
".jsmt")) {
Rtn = -2; // CryptFileName 扩展名必须为:.jsmt
return Rtn;
}
// 用户指定要保存的文件
strPath = strPath.substring(0, strPath.length() - 5);
byte[] bytK1 = getKeyByStr(sKey.substring(0, 16));
byte[] bytK2 = getKeyByStr(sKey.substring(16, 32));
File fileIn = new File(CryptFileName);
if (!fileIn.exists()) {
Rtn = -3; // 需要解密的文件没有找到。
return Rtn;
}
FileInputStream fis = new FileInputStream(fileIn);
byte[] bytIn = new byte[(int) fileIn.length()];
for (int i = 0; i < fileIn.length(); i++) {
bytIn[i] = (byte) fis.read();
}
// 解密
byte[] bytOut = decryptByDES(decryptByDES(bytIn, bytK2), bytK1);
File fileOut = new File(strPath);
fileOut.createNewFile();
FileOutputStream fos = new FileOutputStream(fileOut);
for (int i = 0; i < bytOut.length; i++) {
fos.write((int) bytOut[i]);
}
fos.close();
return Rtn; // 解密成功
} catch (Exception e) {
Rtn = -4; // 其他原因导致的解密失败!
return Rtn;
}
}
/**
* 用DES方法加密输入的字节 bytKey需为8字节长,是加密的密码
*/
private static byte[] encryptByDES(byte[] bytP, byte[] bytKey)
throws Exception {
DESKeySpec desKS = new DESKeySpec(bytKey);
SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
SecretKey sk = skf.generateSecret(desKS);
Cipher cip = Cipher.getInstance("DES");
cip.init(Cipher.ENCRYPT_MODE, sk);
return cip.doFinal(bytP);
}
/**
* 用DES方法解密输入的字节 bytKey需为8字节长,是解密的密码
*/
private static byte[] decryptByDES(byte[] bytE, byte[] bytKey)
throws Exception {
DESKeySpec desKS = new DESKeySpec(bytKey);
SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
SecretKey sk = skf.generateSecret(desKS);
Cipher cip = Cipher.getInstance("DES");
cip.init(Cipher.DECRYPT_MODE, sk);
return cip.doFinal(bytE);
}
/**
* 输入密码的字符形式,返回字节数组形式。 如输入字符串:AD67EA2F3BE6E5AD
* 返回字节数组:{173,103,234,47,59,230,229,173}
*/
private static byte[] getKeyByStr(String str) {
byte[] bRet = new byte[str.length() / 2];
for (int i = 0; i < str.length() / 2; i++) {
Integer itg = new Integer(16 * getChrInt(str.charAt(2 * i))
+ getChrInt(str.charAt(2 * i + 1)));
bRet[i] = itg.byteValue();
}
return bRet;
}
/**
* 计算一个16进制字符的10进制值 输入:0-F
*/
private static int getChrInt(char chr) {
int iRet = 0;
if (chr == "0".charAt(0))
iRet = 0;
if (chr == "1".charAt(0))
iRet = 1;
if (chr == "2".charAt(0))
iRet = 2;
if (chr == "3".charAt(0))
iRet = 3;
if (chr == "4".charAt(0))
iRet = 4;
if (chr == "5".charAt(0))
iRet = 5;
if (chr == "6".charAt(0))
iRet = 6;
if (chr == "7".charAt(0))
iRet = 7;
if (chr == "8".charAt(0))
iRet = 8;
if (chr == "9".charAt(0))
iRet = 9;
if (chr == "A".charAt(0))
iRet = 10;
if (chr == "B".charAt(0))
iRet = 11;
if (chr == "C".charAt(0))
iRet = 12;
if (chr == "D".charAt(0))
iRet = 13;
if (chr == "E".charAt(0))
iRet = 14;
if (chr == "F".charAt(0))
iRet = 15;
return iRet;
}
/**
* 随机产生一个密钥字符串,给输入流进行加密
*
* @param is
* @return
*/
/*public static EncryptInfo encryptInputStream1(InputStream is) {
try {
EncryptInfo encryptInfo = new EncryptInfo(is.available());
String sKey = RandomEncryptString.getEncryptKeyStr();
System.out.println(sKey);
if (sKey.length() != 32) {// 密钥必须是32位 encryptInfo = new
// EncryptInfo(0);
encryptInfo.setEncryptKye("密钥必须是32位");
return encryptInfo;
}
encryptInfo.setEncryptKye(sKey);
byte[] bytK1 = getKeyByStr(sKey.substring(0, 16));
byte[] bytK2 = getKeyByStr(sKey.substring(16, 32));
byte[] bytIn = new byte[is.available()];
int c;
int i = 0;
while ((c = is.read()) != -1) {
bytIn[i] = (byte) c;
} // 加密
encryptInfo
.setBytes(encryptByDES(encryptByDES(bytIn, bytK1), bytK2));
return encryptInfo;
} catch (Exception e) {
return null;
}
}*/
public static byte[] encryptInputStream(InputStream is) {
try {
String sKey = encrypt("jiuqi.com.cn");
if (sKey.length() != 32) {// 密钥必须是32位
return null;
}
byte[] bytK1 = getKeyByStr(sKey.substring(0, 16));
byte[] bytK2 = getKeyByStr(sKey.substring(16, 32));
byte[] bytIn = new byte[is.available()];
int c;
int i = 0;
while ((c = is.read()) != -1) {
bytIn[i] = (byte) c;
i++;
}
byte[] bytes = encryptByDES(encryptByDES(bytIn, bytK1), bytK2);
return bytes;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 利用密钥对文件流进行解密
*
* @param is
* 文件流
* @return
*/
public static byte[] decryptInputStream(InputStream is) {
try {
String encryptKey = encrypt("jiuqi.com.cn");
byte[] bytK1 = getKeyByStr(encryptKey.substring(0, 16));
byte[] bytK2 = getKeyByStr(encryptKey.substring(16, 32));
byte[] bytes = new byte[is.available()];
is.read(bytes);
return decryptByDES(decryptByDES(bytes, bytK2), bytK1);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}// class is over.
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.security.MessageDigest;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
public class EncryptUtil {
/**
* 用户MD5不可逆算法对密钥字符串进行加密
*
* @param inStr
* @return
*/
public static String encrypt(String inStr) {
MessageDigest md = null;
String out = null;
try {
md = MessageDigest.getInstance("MD5");
byte[] digest = md.digest(inStr.getBytes());
out = byte2hex(digest);
} catch (Exception e) {
e.printStackTrace();
}
return out;
}
private static String byte2hex(byte[] b) {
String hs = "";
String stmp = "";
for (int n = 0; n < b.length; n++) {
stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
if (stmp.length() == 1) {
hs = hs + "0" + stmp;
} else {
hs = hs + stmp;
}
}
return hs.toUpperCase();
}
/**
* 加密方法 输入:要加密的文件,密钥字符串 输出: 对输入的文件加密后,保存到同一文件夹下增加了".jsmt"扩展名的文件中。
*/
public static int encryptFile(String FileName, String sKey) {
int Rtn = 0;
try {
// 因为密钥须为32位的字符串,故将用户传递的参数用encrypt方法进行处理;
// (由0-F组成,共32个字符,我们将其拆解为2个16位的密码后进行二次加密运算)如:
// AD67EA2F3BE6E5AD D368DFE03120B5DF
sKey = encrypt(sKey);
System.out.println(sKey);
if (sKey.length() != 32) {
Rtn = -1; // sKey is Wrong. //密码长度必须等于32!
return Rtn;
}
byte[] bytK1 = getKeyByStr(sKey.substring(0, 16));
byte[] bytK2 = getKeyByStr(sKey.substring(16, 32));
File fileIn = new File(FileName);
if (!fileIn.exists()) {
Rtn = -2; // 需要加密的文件没有找到。
return Rtn;
}
FileInputStream fis = new FileInputStream(fileIn);
byte[] bytIn = new byte[(int) fileIn.length()];
for (int i = 0; i < fileIn.length(); i++) {
bytIn[i] = (byte) fis.read();
}
// 加密
byte[] bytOut = encryptByDES(encryptByDES(bytIn, bytK1), bytK2);
String fileOut = fileIn.getPath() + ".jsmt";
FileOutputStream fos = new FileOutputStream(fileOut);
for (int i = 0; i < bytOut.length; i++) {
fos.write((int) bytOut[i]);
}
fos.close();
return Rtn;
} catch (Exception e) {
Rtn = -3; // 其他原因导致的加密失败!
return Rtn;
}
}
/**
* 解密函数 输入: 要解密的文件,密钥字符串 输出: 对制定的文件进行解密处理,保存到用户指定的文件中。(注:待解密的文件扩展名必须为:.jsmt)
*/
public static int decryptFile(String CryptFileName, String sKey) {
int Rtn = 0; // 默认的返回值为0,成功!
try {
// 因为密钥须为32位的字符串,故将用户传递的参数用encrypt方法进行处理;
// (由0-F组成,共32个字符,我们将其拆解为2个16位的密码后进行二次解密运算)如:
// AD67EA2F3BE6E5AD D368DFE03120B5DF
sKey = encrypt(sKey);
if (sKey.length() != 32) {
Rtn = -1; // sKey is Wrong. //密码长度必须等于32!
return Rtn;
}
String strPath = CryptFileName;
if (!strPath.substring(strPath.length() - 5).toLowerCase().equals(
".jsmt")) {
Rtn = -2; // CryptFileName 扩展名必须为:.jsmt
return Rtn;
}
// 用户指定要保存的文件
strPath = strPath.substring(0, strPath.length() - 5);
byte[] bytK1 = getKeyByStr(sKey.substring(0, 16));
byte[] bytK2 = getKeyByStr(sKey.substring(16, 32));
File fileIn = new File(CryptFileName);
if (!fileIn.exists()) {
Rtn = -3; // 需要解密的文件没有找到。
return Rtn;
}
FileInputStream fis = new FileInputStream(fileIn);
byte[] bytIn = new byte[(int) fileIn.length()];
for (int i = 0; i < fileIn.length(); i++) {
bytIn[i] = (byte) fis.read();
}
// 解密
byte[] bytOut = decryptByDES(decryptByDES(bytIn, bytK2), bytK1);
File fileOut = new File(strPath);
fileOut.createNewFile();
FileOutputStream fos = new FileOutputStream(fileOut);
for (int i = 0; i < bytOut.length; i++) {
fos.write((int) bytOut[i]);
}
fos.close();
return Rtn; // 解密成功
} catch (Exception e) {
Rtn = -4; // 其他原因导致的解密失败!
return Rtn;
}
}
/**
* 用DES方法加密输入的字节 bytKey需为8字节长,是加密的密码
*/
private static byte[] encryptByDES(byte[] bytP, byte[] bytKey)
throws Exception {
DESKeySpec desKS = new DESKeySpec(bytKey);
SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
SecretKey sk = skf.generateSecret(desKS);
Cipher cip = Cipher.getInstance("DES");
cip.init(Cipher.ENCRYPT_MODE, sk);
return cip.doFinal(bytP);
}
/**
* 用DES方法解密输入的字节 bytKey需为8字节长,是解密的密码
*/
private static byte[] decryptByDES(byte[] bytE, byte[] bytKey)
throws Exception {
DESKeySpec desKS = new DESKeySpec(bytKey);
SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
SecretKey sk = skf.generateSecret(desKS);
Cipher cip = Cipher.getInstance("DES");
cip.init(Cipher.DECRYPT_MODE, sk);
return cip.doFinal(bytE);
}
/**
* 输入密码的字符形式,返回字节数组形式。 如输入字符串:AD67EA2F3BE6E5AD
* 返回字节数组:{173,103,234,47,59,230,229,173}
*/
private static byte[] getKeyByStr(String str) {
byte[] bRet = new byte[str.length() / 2];
for (int i = 0; i < str.length() / 2; i++) {
Integer itg = new Integer(16 * getChrInt(str.charAt(2 * i))
+ getChrInt(str.charAt(2 * i + 1)));
bRet[i] = itg.byteValue();
}
return bRet;
}
/**
* 计算一个16进制字符的10进制值 输入:0-F
*/
private static int getChrInt(char chr) {
int iRet = 0;
if (chr == "0".charAt(0))
iRet = 0;
if (chr == "1".charAt(0))
iRet = 1;
if (chr == "2".charAt(0))
iRet = 2;
if (chr == "3".charAt(0))
iRet = 3;
if (chr == "4".charAt(0))
iRet = 4;
if (chr == "5".charAt(0))
iRet = 5;
if (chr == "6".charAt(0))
iRet = 6;
if (chr == "7".charAt(0))
iRet = 7;
if (chr == "8".charAt(0))
iRet = 8;
if (chr == "9".charAt(0))
iRet = 9;
if (chr == "A".charAt(0))
iRet = 10;
if (chr == "B".charAt(0))
iRet = 11;
if (chr == "C".charAt(0))
iRet = 12;
if (chr == "D".charAt(0))
iRet = 13;
if (chr == "E".charAt(0))
iRet = 14;
if (chr == "F".charAt(0))
iRet = 15;
return iRet;
}
/**
* 随机产生一个密钥字符串,给输入流进行加密
*
* @param is
* @return
*/
/*public static EncryptInfo encryptInputStream1(InputStream is) {
try {
EncryptInfo encryptInfo = new EncryptInfo(is.available());
String sKey = RandomEncryptString.getEncryptKeyStr();
System.out.println(sKey);
if (sKey.length() != 32) {// 密钥必须是32位 encryptInfo = new
// EncryptInfo(0);
encryptInfo.setEncryptKye("密钥必须是32位");
return encryptInfo;
}
encryptInfo.setEncryptKye(sKey);
byte[] bytK1 = getKeyByStr(sKey.substring(0, 16));
byte[] bytK2 = getKeyByStr(sKey.substring(16, 32));
byte[] bytIn = new byte[is.available()];
int c;
int i = 0;
while ((c = is.read()) != -1) {
bytIn[i] = (byte) c;
} // 加密
encryptInfo
.setBytes(encryptByDES(encryptByDES(bytIn, bytK1), bytK2));
return encryptInfo;
} catch (Exception e) {
return null;
}
}*/
public static byte[] encryptInputStream(InputStream is) {
try {
String sKey = encrypt("jiuqi.com.cn");
if (sKey.length() != 32) {// 密钥必须是32位
return null;
}
byte[] bytK1 = getKeyByStr(sKey.substring(0, 16));
byte[] bytK2 = getKeyByStr(sKey.substring(16, 32));
byte[] bytIn = new byte[is.available()];
int c;
int i = 0;
while ((c = is.read()) != -1) {
bytIn[i] = (byte) c;
i++;
}
byte[] bytes = encryptByDES(encryptByDES(bytIn, bytK1), bytK2);
return bytes;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 利用密钥对文件流进行解密
*
* @param is
* 文件流
* @return
*/
public static byte[] decryptInputStream(InputStream is) {
try {
String encryptKey = encrypt("jiuqi.com.cn");
byte[] bytK1 = getKeyByStr(encryptKey.substring(0, 16));
byte[] bytK2 = getKeyByStr(encryptKey.substring(16, 32));
byte[] bytes = new byte[is.available()];
is.read(bytes);
return decryptByDES(decryptByDES(bytes, bytK2), bytK1);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}// class is over.