ws694617206 发表于 2013-2-7 03:40:53

对国库数据加密解密

/** ** 说明:对国库数据加密、解密 */ package com.cfcc.tas.util;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.EOFException;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.nio.ByteBuffer;import java.util.Calendar;import java.util.Random;public class TreasuryEncrypt {//二维数组,61*8;private final static String ENCRYPT_KEY [][]={{"?1i%d3Kx"},{"s8@8$!*i"},{"d7J:SFw4"},{"l6piz3Gn"}, {"Rs5t|o&#"},{"4s*m-y4;"},{"3o34%x:W"},{"a2e+FDKQ"}, {"s{OCS$1?"},{"sAUI<>2a"},{"2_gf<3vQ"},{"b8&o<fH]"}, {"7ds?.asd"},{"sd6sft4V"},{"ds5QTP{q"},{"n4^/?Sys"}, {"sfdteib8"},{"b2s?>LK}"},{"1/dti.length();//文件标志(windows)private final static byte[] WIN_FILE_SIGNAL = {13,10};private final static byte[] WIN_STR_SIGNAL = {35,35};private final static int MAX_HEAD_LEN = 4;//分节符类型public final static int SIGNAL_TYPE_NULL = -1;public final static int SIGNAL_TYPE_STR = 0;public final static int SIGNAL_TYPE_FILE = 1;//加密和解密字符串时使用,如果字符串中不包含解密用的key,解密字符串时传入改值.public final static int KEY_NULL = -1;/* * 说明: 在TCBS中主要使用了对文件中的内容进行加解密. * 在TBS中,对字符串加密使用了两种方式,一种是使用回车换行(换行)做为分割密钥和字符串的标志, * 一种是使用两个'#', 就是WIN_FILE_SIGNAL 和 WIN_STR_SIGNAL. * 文件内容的加密使用WIN_STR_SIGNAL. * 修改解密方法,文件加密有两种:一种首行为密钥索引,一种不是 *//** * 对字符串加密 * @param srcStr * @param sinalType 分节符类型 0:字符串类型 其它:文件类型 * @return * @throws Exception */public static String Encrypt(String srcStr, int sinalType) throws Exception{if(srcStr == null || srcStr.trim().length() == 0){throw new Exception("被加密的字符串不能为空!");}//if(sinalType == SIGNAL_TYPE_STR){return encryptStr(srcStr, WIN_STR_SIGNAL);}else{return encryptStr(srcStr, WIN_FILE_SIGNAL);}}/** * 对字符串解密 (gkfxjmzjstr) * @param srcStr: 被加密后的字符串,可以带密钥也可以不带密钥. 不带密钥时需要在参数nKeyIndex传入密文使用的密钥; * @param nKeyIndex : 参数srcStr中没有有密钥时,使用 nKeyIndex <= 60 并且 nKeyIndex >= 0; * @param sinalType : 字符串中没有密钥时,该值无效;文件中使用回车换行(\r\n或\n)做为分割符. * @return * @throws Exception */public static String Decrypt(String srcStr, int nKeyIndex, int sinalType) throws Exception {//byte keyIndex = 0;byte decrypt[] = null;//不在key范围内的字符串的key,认为字符串中包含key, 字符串中包含keyif(nKeyIndex < 0 || nKeyIndex > 60){if(srcStr == null || srcStr.trim().length() == 0){throw new Exception("被解密的字符串不能为空!");}else if(srcStr.trim().length() <= MAX_HEAD_LEN){throw new Exception("被解密的字符串格式错误!");}//if(sinalType < SIGNAL_TYPE_STR){throw new Exception("被解密的字符串格式错误!");}//取keyint idx = 0;if(sinalType == SIGNAL_TYPE_STR){idx = srcStr.indexOf(new String(WIN_STR_SIGNAL));keyIndex = (byte)Integer.parseInt(srcStr.substring(0, idx));}else{idx = srcStr.indexOf(new String(WIN_FILE_SIGNAL));keyIndex = (byte)readStrSignal(srcStr);}//if(keyIndex > 60) {throw new Exception("字符串格式错误!");}if(idx < 0) return null;decrypt = srcStr.substring(idx + 2, srcStr.length()).getBytes();}else{keyIndex = (byte)nKeyIndex;decrypt = srcStr.getBytes();}return new String(decrypt(decrypt, decrypt.length, keyIndex));}/** * 对文件加密(gkjmzj) * @param srcFile * @param dstFile * @throws Exception */public static void Encrypt(String srcFile, String dstFile) throws Exception{File inFile = new File(srcFile);if(!inFile.exists()){throw new Exception("被加密的文件不存在!");}//空文件;if(inFile.length() == 0){throw new Exception("被加密的文件为空!");}File outFile = new File(dstFile);//if(!outFile.exists()){outFile.createNewFile();}//使用缓存的方式输入DataInputStream fin = new DataInputStream(new BufferedInputStream(new FileInputStream(inFile)));//使用缓存的方式输出DataOutputStream fout = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(outFile)));//byte nKeyIndex = genKeyIndex();//文件开始标志fout.write(String.valueOf(nKeyIndex).getBytes());fout.write(WIN_FILE_SIGNAL);byte[] srcBuff = new byte;int readLen = -1;//加密文件try {while(true){readLen = fin.read(srcBuff);if(readLen < 0){break;}fout.write(encrypt(srcBuff, readLen, nKeyIndex));}}catch(EOFException e){throw new Exception(e.getMessage());}finally{fout.flush();fin.close();fout.close();}}/** * 解密文件(gkfxjmzj) * @param srcFile * @param dstFile * @bFisrtLineEncrypt 文件内容的首行是密钥吗? * @throws Exception */public static void Decrypt(String srcFile, String dstFile, boolean bKeyIsFirstLine) throws Exception{File inFile = new File(srcFile);if(!inFile.exists()){throw new Exception("被解密的文件不存在!");}//空文件;if(inFile.length() == 0){throw new Exception("被解密的文件为空!");}File outFile = new File(dstFile);//判断文件能否打开if(!outFile.exists()){outFile.createNewFile();}//outFile.createNewFile();//使用缓存的方式输入DataInputStream fin = new DataInputStream(new BufferedInputStream(new FileInputStream(inFile)));//使用缓存的方式输出DataOutputStream fout = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(outFile)));byte keyIndex = 0;//读文件的首行if(!bKeyIsFirstLine){//读文件的首行,直接写入文件;String line = readLine(fin);if(line == null || line.trim().length() == 0){throw new Exception("文件格式错误!");}//line += "\r\n";fout.write(line.getBytes());}//读密钥keyIndex = (byte)readFileSignal(fin);if(keyIndex > ENCRYPT_KEY.length || keyIndex < 0){throw new Exception("文件格式错误!");}byte[] srcBuff = new byte;int readLen = -1;//解密文件try{while(true){readLen = fin.read(srcBuff);if(readLen < 0){break;}fout.write(decrypt(srcBuff, readLen, keyIndex));}}catch(EOFException e){throw new Exception(e.getMessage());}finally{fin.close();fout.flush();fout.close();}}/** * @deprecated * gkjmzjfl * @param inFileName * @param outFileName * @param key * @return */public static void EncryptUnix(String srcFile, String dstFile) throws Exception{//判断文件能否打开File inFile = new File(srcFile);if(!inFile.exists()){throw new Exception("被加密的文件不存在!");}//空文件;if(inFile.length() == 0){throw new Exception("被加密的文件为空!");}File outFile = new File(dstFile);//if(!outFile.exists()){outFile.createNewFile();}//使用缓存的方式输入DataInputStream fin = new DataInputStream(new BufferedInputStream(new FileInputStream(inFile)));//使用缓存的方式输出DataOutputStream fout = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(outFile)));//byte keyIndex = genKeyIndex();byte firstLine = 0;byte srcByte;byte dstByte;//byte keyBytes[] = ENCRYPT_KEY.getBytes(); int keyBytesIdx = 0;try{while(true){//srcByte = fin.readByte();if(firstLine == 2){dstByte = xor(srcByte, keyBytes);//if(keyBytesIdx == KEY_LENGTH){keyBytesIdx = 0;}}else{dstByte = srcByte;}fout.write(dstByte);//if(dstByte == 13 && firstLine == 0){firstLine = 1;}if(dstByte == 10 && firstLine == 1){fout.write(keyIndex);firstLine = 2;}}}catch(EOFException e){}fin.close();fout.close();}/** * @deprecated * 原名:DLL_Encrypt * @param inKey : 密钥 * @param inData: 被加密或解密的数据 * @param bFlag : true 使用 inKey 对 inData 加密 *   false 使用 inKey 对 inData 解密; * @return */public static String Encrypt(String inKey, String inData, boolean bFlag) throws Exception {if(inKey == null || inKey.trim().length() == 0 || inData == null || inData.trim().length() == 0){throw new Exception("密钥和数据不能为空!");}//byte[] keyBytes = inKey.getBytes();byte[] dataBytes = inData.getBytes();int keyLen = keyBytes.length;int dataLen = dataBytes.length;ByteBuffer buff = null;//计算key的和int keySum = 0;for(int i = 0; i < keyLen; i++){keySum += keyBytes;}//int keyValue = 0;//加密if(bFlag){//buff = ByteBuffer.allocate(dataLen * 5);//for(int i = 0; i < dataLen; i++){keyValue = keySum;//keyValue += dataBytes;//keyValue ^= keyBytes;//buff.put(String.format("%05d", keyValue).getBytes());}} else {//解密String subData = "";//被加密后的数据是5的整数倍if(dataLen % 5!=0){throw new Exception("数据格式错误!");}//实际数据的长度dataLen = dataLen / 5;buff = ByteBuffer.allocate(dataLen);//for(int i = 0; i < dataLen; i++){subData = inData.substring(i * 5, (i + 1) * 5);//keyValue = Integer.valueOf(subData).intValue();//keyValue ^= keyBytes;//keyValue -= keySum;//buff.put((byte)keyValue);}}return new String(buff.array());}/** * 对字符串加密(gkjmzjstr) * @param srcStr * @param sinal : 分节符类型 字符类型和文件类型 * @return * @throws Exception */private static String encryptStr(String srcStr, byte sinal[]) throws Exception{if(srcStr == null || srcStr.trim().length() == 0){throw new Exception("被加密的字符串不能为空!");}//取密钥byte keyIndex = genKeyIndex();//取字节流byte srcBytes[] = srcStr.getBytes();ByteBuffer buff = ByteBuffer.allocate(srcBytes.length + 2);//写密钥标志buff.put(sinal);//buff.put(encrypt(srcBytes, srcBytes.length, keyIndex));return Integer.toString(keyIndex)+ new String(buff.array());}/** * 对字节数组加密 * @param srcBytes * @param nSrcBytes * @param keyIndex * @return * @throws Exception */private static byte[] encrypt(byte[] srcBytes, int nSrcBytes, byte keyIndex) throws Exception{ByteBuffer buff = ByteBuffer.allocate(nSrcBytes);//加密byte keyBytes[] = ENCRYPT_KEY.getBytes();intkeyByteIdx = 0;for(int i = 0; i< nSrcBytes; i++) {buff.put(xor(srcBytes, keyBytes));//if(keyByteIdx == KEY_LENGTH){keyByteIdx= 0;}}return buff.array();}/** * 对字节数据解密 * @param srcBytes * @param nSrcBytes * @param keyIndex * @return * @throws Exception */private static byte[] decrypt(byte[] srcBytes, int nSrcBytes, byte keyIndex) throws Exception {//校验密钥索引if(keyIndex > 60) {throw new Exception("字符串格式错误!");}//解密ByteBuffer outBuff = ByteBuffer.allocate(nSrcBytes);byte keyItems[] = ENCRYPT_KEY.getBytes();int keyItemIdx = 0;for(int i = 0; i < nSrcBytes; i++){outBuff.put(xor(srcBytes, keyItems));if(keyItemIdx == KEY_LENGTH){keyItemIdx= 0;}}return outBuff.array();}/** * 使用 格林威治标准时间作为随机数的种子,生成密钥索引 * @return */private static byte genKeyIndex(){//生成随机数Random rand = new Random(Calendar.getInstance().getTimeInMillis());long randValue = rand.nextInt();//取无符号数据;if(randValue < 0){randValue = (0xFFFFFFFFL + randValue) + 1;}//取模Long result = randValue % 60;//return result.byteValue();}/** * 异或操作(不能对字节进行异或操作,所以添加该方法) * @param src1 * @param src2 * @return */private static byte xor(byte src1, byte src2){int result = Byte.valueOf(src1).intValue() ^ Byte.valueOf(src2).intValue();return Integer.valueOf(result).byteValue(); }/** * 取文件头部的标志 * @param fin * @return * @throws IOException * Windows中使用'\r\n'(0xD 0xA)回车换行, Linux 或 Unix 中使用'\n'(0xA)表示回车换行; */private static int readFileSignal(DataInputStream fin) throws IOException{String sIndex = readKeyIndex(fin);if(sIndex != null){return Integer.parseInt(sIndex);}else{return -1;}}/** * 取文件头部的标志 * @param fin * @return * @throws IOException */private static int readStrSignal(String fin) throws IOException{String sIndex = readKeyIndex(fin);if(sIndex != null){return Integer.parseInt(sIndex);}else{return -1;}}/** * 取文件中密钥的索引 * @param fin * @return * @throws IOException */private static String readKeyIndex(DataInputStream fin) throws IOException {char c = 0;String sIndex = "";int len = 0;//索引 + 标记不超过 6 个字节while(len < 6){c = (char)fin.readByte();len++;if(c == '\n' || c == '\r'){if(c == '\r'){c = (char)fin.readByte();len++;if(c == '\n'){return sIndex;}else{sIndex += c;}}else{return sIndex;}}else{sIndex += c;}}return null;}/** * 取文件中密钥的索引 * @param lines * @return * @throws IOException */private static String readKeyIndex(String lines) throws IOException {char c = 0;String sIndex = "";int len = 0;//索引 + 标记不超过 6 个字节, 由密钥数组大小决定while(len < 6){c = lines.charAt(len++);if(c == '\n' || c == '\r'){if(c == '\r'){c = lines.charAt(len++);if(c == '\n'){return sIndex;}else{sIndex += c;}}else{return sIndex;}}else{sIndex += c;}}return null;}/** * 取文件中密钥的索引 * @param fin * @return * @throws IOException */private static String readLine(DataInputStream fin) throws IOException {char c = 0;String sLine = "";int len = 0;try{//索引 + 标记不超过 6 个字节while(true){c = (char)fin.readByte();len++;if(c == '\n' || c == '\r'){if(c == '\r'){c = (char)fin.readByte();len++;if(c == '\n'){return sLine;}else{sLine += c;}}else{return sLine;}}else{sLine += c;}}}catch(EOFException e){return sLine;}}}
页: [1]
查看完整版本: 对国库数据加密解密