最近要实现一个对数据字典中上传的文件流的加密处理,并存入缓存的处理;在读取缓存时,若不存在此数据字典的缓存,则获取其加密文件,再将文件保存到缓存的处理操作;
重点讲对文件流的加密和解密,废话不多说,看红色代码:
/**
*
* @Description: 保存数据字典并缓存
* @author
* @param sysCodeAttr
* @param file
* @return
*/
public WrappedResult saveOrUpdate(SysCodeAttrBO sysCodeAttr, MultipartFile file) throws Exception {
// 判断参数值是否包含XSS非法字符
if(this.isXSS(sysCodeAttr.getCodeValue())){
return WrappedResult.failedWrappedResult("参数值中包含非法字符串!");
}
//判断已存在该参数名称 如果存在则返回错误
int count = this.sysCodeAttrDao.getSysCodeNum(sysCodeAttr);
if(count > 0){
return WrappedResult.failedWrappedResult("已存在相同名称的参数!");
}
//保存文件
if (null != file && file.getSize() > 0) {
String fileType = FileType.getFileType(file.getInputStream());
if(StringUtil.isNullOrEmpty(fileType)){
String fileName = file.getOriginalFilename();
int i = fileName.lastIndexOf('.');
if( i > 0){
fileType = fileName.substring(i+1);
}
}
if(!Arrays.asList(allowFileTypes).contains(fileType)){
return WrappedResult.failedWrappedResult("上传文件类型错误,请上传txt或者图片!");
}
Map
//加密特定的流文件
if(AppConstants.APP_PAY_PARAMS_PLATFORM.equals(sysCodeAttr.getCodeName()) && fileType.contains("txt")){
InputStream encryptInputStream = FileUtil.encryptLocalTxtFile(file);
// 将文件存储到本地磁盘
FileUtil.saveFile(encryptInputStream, "/sys_code/", UUID.randomUUID()
.toString() + "." + fileType, result);
}else{
FileUtil.saveFile(file, "/sys_code/", UUID.randomUUID()
.toString() + "." + fileType , result);
}
sysCodeAttr.setFileUrl(result.get("filePath"));
client.put(CommonConstants.SYSCODE_KEY_PREFIX_URL + sysCodeAttr.getCodeName(), sysCodeAttr.getFileUrl());
}
//保存参数
.... (此处保存参数到数据库)
//更新redis缓存
try {
client.put(CommonConstants.SYSCODE_KEY_PREFIX + sysCodeAttr.getCodeName(), sysCodeAttr.getCodeValue());
} catch (Exception e) {
throw new BusinessException("操作失败,参数更新redis缓存失败!", e);
}
return WrappedResult.successWrapedResult("操作成功!");
}
/**
* @Description: 将TXT文件流加密后返回输入流
* @author
* @date 2017年9月19日 下午5:00:35
* @param file
* @return InputStream
*/
public static InputStream encryptLocalTxtFile(MultipartFile file){
String data;//原字符串
String encryptData;//加密字符串
StringBuilder encryptStringBuilder = new StringBuilder();
try {
if (file.getOriginalFilename().contains(".txt")) {
InputStream in =file.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
while ((data = br.readLine()) != null ) {
//去除所有空格并加密
encryptData=EncryptUtil.encrypt(data.replaceAll(" +",""));
encryptStringBuilder.append(System.lineSeparator() + encryptData);
}
br.close();
InputStream out = new ByteArrayInputStream(encryptStringBuilder.toString().getBytes());
return out;
} else {
log.error("所传文件为空或文件类型不是.TXT类型,所传文件名为:"+file.getName());
return null;
}
} catch (IOException e) {
log.error("TXT文件读取异常:"+e);
return null;
}
好了,接下来就是用的时候的,需要使用文件中的内容:
/**
* @Description: 刷新支付参数的缓存--支付参数存在.txt文件中
* @author
* @date 2017年9月19日 上午9:33:56
* @param codeName
* @return
*/
public WrappedResult refreshAppPayParams(String codeName) {
// 查询数据库该参数的url
SysCodeAttr out = getObjectByName(codeName);
if (out != null && StringUtil.isNotNullOrNotEmpty(out.getFileUrl())) {
// 调用导入,并刷新TXT文件的缓存
try {
Map
if (null != relMap) {
for (Entry
client.put(CommonConstants.SYSCODE_KEY_PREFIX + entry.getKey(),
entry.getValue().toString());
}
}
} catch (IOException e) {
return WrappedResult.failedWrappedResult("刷新失败");
}
}
return WrappedResult.successWrapedResult("刷新成功");
}
读取文件并解密的方法如下:
/**
* @Description: 读取远程服务器特定的加密TXT文件内容,将其解密并转为MAP,键值对信息用#分割
* @author
* @date 2017年9月18日 下午3:29:01
* @param filePath
* @return
* @throws IOException
*/
public static Map
throws IOException {
String encryptData;// 加密的字符串
String decryptData;// 解密字符串
String[] readData;// 解密后的数组
Map
try {
if (StringUtil.isNotNullOrNotEmpty(filePath)) {
String basePath = getFileRootPath();
File file = new File(basePath, filePath);
if (filePath.startsWith(basePath)) {
file = new File(filePath);
}
if (!file.exists()) {
log.error("文件不存在:" + filePath);
return null;
}
BufferedReader br = new BufferedReader(new InputStreamReader(
new FileInputStream(file)));
while ((encryptData = br.readLine()) != null) {
decryptData = EncryptUtil.decrypt(encryptData);
// 去除所有空格
readData = (decryptData.replaceAll(" +", "")).split("#");
if (readData.length == 2) {
// 赋值给MAP
result.put(readData[0], readData[1]);
}
}
br.close();
} else {
log.error("所传文件为空或文件类型不是.TXT类型,所传文件url为:" + filePath);
return null;
}
} catch (IOException e) {
log.error("TXT文件读取异常:" + e);
}
return result;
}
加解密工具类如下:
/***
*
* @Description: 传输过程中敏感信息加密处理
* @author
* @date 2017年5月17日
*/
public class EncryptUtil {
private static String key = "1234567890000000";
private static String ivStr = "1234567890000000";
/**
*
* @Description:加密
* @author
* @param src
* @return
*/
public static String encrypt(String src) {
byte[] raw = key.getBytes();
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
byte[] encrypted =null;
try{
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");// "算法/模式/补码方式"0102030405060708
IvParameterSpec iv = new IvParameterSpec(ivStr.getBytes());// 使用CBC模式,需要一个向量iv,可增加加密算法的强度
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
encrypted= cipher.doFinal(src.getBytes());
}catch(Exception e){
throw new BusinessException(
BusinessError.RESULTCODE_SYSTEM_ERROR.getStatus(),
"加密异常");
}
return Base64.encodeBase64String(encrypted);
}
/**
*
* @Description: 解密
* @author
* @param src
* @return
*/
public static String decrypt(String src) {
try {
byte[] raw = key.getBytes("ASCII");
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
IvParameterSpec iv = new IvParameterSpec(ivStr.getBytes());
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
byte[] encrypted1 = Base64.decodeBase64(src);// 先用base64解密
byte[] original = cipher.doFinal(encrypted1);
String originalString = new String(original, "UTF-8");
return originalString;
} catch (Exception ex) {
throw new BusinessException(
BusinessError.RESULTCODE_SYSTEM_ERROR.getStatus(),
"解密异常");
}
}
}
文件内容如下图格式:
编写不易,希望大家点个赞,哈哈!分享一下.