package com.yinhoo.ca.utils;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.util.Arrays;
import javax.crypto.Cipher;
import org.apache.commons.io.FileUtils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.yinhoo.ca.helper.KeyPairLoader;
/**
* 用于进行文件的RSA加密
*
* @author ming.chen
* @date 2011-2-14
* @version $Revision$
*/
public class RSAUtils {
private static Logger logger = LoggerFactory.getLogger(RSAUtils.class);
private static final int ECODE_EACH_READ_SIZE = 100;
private static final int DECODE_EACH_READ_SIZE = 128;
/**
* 对文件进行RSA加密
*
* @param ip
* 要加密的客户端ip
* @param srcFilePath
* 要加密文件的完整路径
*/
public static void encryptFile(String ip, String srcFilePath) {
if (KeyPairLoader.getKeyPairByIp(ip) == null) {
logger.warn("No Encode key bind on ip:" + ip);
return;
}
File file = new File(srcFilePath);
if (!file.exists() || !file.isFile()) {
logger.warn(String.format("%s is not file.", srcFilePath));
return;
}
try {
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", new BouncyCastleProvider());
cipher.init(Cipher.ENCRYPT_MODE, KeyPairLoader.getKeyPairByIp(ip).getPrivate());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] bytes = FileUtils.readFileToByteArray(file);
for (int i = 0; i < bytes.length; i += ECODE_EACH_READ_SIZE) {
int end = i + ECODE_EACH_READ_SIZE;
byte[] toEncrypt = Arrays.copyOfRange(bytes, i, end < bytes.length ? end : bytes.length);
byte[] segment = cipher.doFinal(toEncrypt);
baos.write(segment, 0, segment.length);
}
baos.flush();
byte[] result = baos.toByteArray();
FileUtils.writeByteArrayToFile(file, result);
}
catch (Exception e) {
logger.error(String.format("Error occur when encrypt file: %s", srcFilePath), e);
}
}
/**
* 对文件进行RSA解密
*
* @param ip
* 要解密的客户端ip
* @param srcFilePath
* 要解密文件的完整路径
*/
public static void decryptFile(String ip, String srcFilePath) {
if (KeyPairLoader.getKeyPairByIp(ip) == null) {
logger.warn("No Encode key bind on ip:" + ip);
return;
}
File file = new File(srcFilePath);
if (!file.exists() || !file.isFile()) {
logger.warn(String.format("%s is not file.", srcFilePath));
return;
}
try {
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", new BouncyCastleProvider());
cipher.init(Cipher.DECRYPT_MODE, KeyPairLoader.getKeyPairByIp(ip).getPublic());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] bytes = FileUtils.readFileToByteArray(file);
for (int i = 0; i < bytes.length; i += DECODE_EACH_READ_SIZE) {
int end = i + DECODE_EACH_READ_SIZE;
byte[] toDecrypt = Arrays.copyOfRange(bytes, i, end < bytes.length ? end : bytes.length);
byte[] segment = cipher.doFinal(toDecrypt);
baos.write(segment, 0, segment.length);
}
baos.flush();
byte[] result = baos.toByteArray();
FileUtils.writeByteArrayToFile(file, result);
}
catch (Exception e) {
logger.error(String.format("Error occur when decrypt file: %s", srcFilePath), e);
}
}
}