【发布时间】:2019-09-28 08:07:31
【问题描述】:
我需要在上传时加密文件,在下载时解密文件。
我编写了一个逻辑来在 REST spring 应用程序中上传和下载文件,但无法加密和解密。请检查我的代码
控制器 - 上传逻辑
@CrossOrigin(maxAge = 4800, allowCredentials = "false")
@RequestMapping(value = "/multipleSave/{module}/{reminderId}", method = RequestMethod.POST)
public @ResponseBody String uploadMultiple(@RequestParam("file") MultipartFile[] files,
@PathVariable String module,@PathVariable int reminderId,
HttpSession session, HttpServletResponse response, HttpServletRequest request) {
long limit = 2 * 1024 * 1024;
String fileName = null;
String msg = "";
String modulePath="";
modulePath = path+"/"+module;
if(files.length > 5){
throw new FileUploadException("Max number of Files to upload is 5");
}
if (files != null && files.length > 0) {
for (int i = 0; i < files.length; i++) {
try {
if(files[i].getSize() > limit){
throw new FileUploadException("File upload Limit is 2 mb, please check the size");
}
fileName = files[i].getOriginalFilename();
String ext = fileName.substring(fileName.lastIndexOf('.') + 1);
String dateTime = getCurrentDateTime();
String localDate = dateTime.toString().replaceAll("[^0-9]", "");
String renameFile = fileName.substring(0,fileName.lastIndexOf('.'))+"_"+localDate.toString()+"."+ext;
NRICSecurity sec = new NRICSecurity();
sec.encrypt(renameFile,modulePath+"/"+renameFile+".enc");
} catch (Exception e) {
//Exception
}
}
}
}
renameFile 给出 FileNotFoundException,我如何从 MultipartFile 定义整个路径
服务 - 下载逻辑
public void downloadFile(HttpServletResponse response, int fileId) throws FileNotFoundException, IOException {
FileUpload fileUpload = fileDAO.getFileByFileId(fileId);
if (fileUpload != null) {
try{
new NRICSecurity().decrypt(fileUpload.getFilePath()+"/"+fileUpload.getFileNameOrg()+".enc", fileUpload.getFileName());
}catch(Exception e){
}
Path file = Paths.get(fileUpload.getFilePath(), fileUpload.getFileNameOrg());
if (Files.exists(file)) {
try {
String contentType = Files.probeContentType(file);
response.setContentType(contentType);
response.setHeader("Content-disposition", "attachment; filename=" + fileUpload.getFileName());
Files.copy(file, response.getOutputStream());
response.getOutputStream().flush();
} catch (IOException ex) {
}
} else {
response.sendError(404, new FileNotFoundException().getMessage());
}
} else {
response.sendError(404, new FileNotFoundException().getMessage());
}
}
使用RSA加密和解密方法
//------File Encryption and Decryption---------
/**
* Encrypt file
* @param filename
* @param outFile
*/
public void encrypt(String fileName, String outFile){
String publickeyFile = mybundle.getString("r365.private.key");
try{
PublicKey publicKey = readPublicKey(publickeyFile);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
processFile(cipher,fileName,outFile);
}catch(Exception e){
e.printStackTrace();
}
}
/**
* Decrypt File
* @param filename
* @param outFile
*/
public void decrypt(String fileName, String outFile){
String privateKeyFile = mybundle.getString("r365.private.key");
try{
PrivateKey privateKey = readPrivateKey(privateKeyFile);
Cipher decryptChiper = Cipher.getInstance("RSA");
decryptChiper.init(Cipher.DECRYPT_MODE, privateKey);
processFile(decryptChiper,fileName,outFile);
}catch(Exception e){
e.printStackTrace();
}
}
private void processFile(Cipher ci,InputStream in,OutputStream out)
throws javax.crypto.IllegalBlockSizeException,
javax.crypto.BadPaddingException,
java.io.IOException
{
byte[] ibuf = new byte[1024];
int len;
while ((len = in.read(ibuf)) != -1) {
byte[] obuf = ci.update(ibuf, 0, len);
if ( obuf != null ) out.write(obuf);
}
byte[] obuf = ci.doFinal();
if ( obuf != null ) out.write(obuf);
}
private void processFile(Cipher ci,String inFile,String outFile)
throws javax.crypto.IllegalBlockSizeException,
javax.crypto.BadPaddingException,
java.io.IOException
{
try (FileInputStream in = new FileInputStream(inFile);
FileOutputStream out = new FileOutputStream(outFile)) {
processFile(ci, in, out);
}
}
如果我通过整个路径传递 inFile 和 outFile,加密和解密方法正在工作,在上传时我无法从 MultiPartFile[] 文件中获取路径,如果我尝试下载它只会在浏览器中下载而不是在服务器位置。
【问题讨论】:
-
在上传时代替 fileName 我尝试传递 inputStream = files[i].getInputStream 但得到 javax.crypto.IllegalBlockSizeException: Data must not be longer than 245 bytes。我正在使用
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); keyGen.initialize(2048);生成密钥。为什么投反对票?任何建议 -
HTTPS 为您提供所需的一切。
标签: java spring file file-upload rsa