Browse Source

open

master
pioneer 2 years ago
commit
9e97116f15
  1. 6
      README.md
  2. BIN
      lib/finekit-10.0.jar
  3. BIN
      lib/jna-4.2.2.jar
  4. BIN
      lib/jna-platform-4.2.2.jar
  5. 30
      plugin.xml
  6. 36
      src/main/java/com/fr/plugin/gb/LocaleFinder.java
  7. 57
      src/main/java/com/fr/plugin/gb/export/ExcelPlusExporter.java
  8. 244
      src/main/java/com/fr/plugin/gb/filter/BodyRequestWrapper.java
  9. 45
      src/main/java/com/fr/plugin/gb/filter/CustomExcelImportDeal.java
  10. 45
      src/main/java/com/fr/plugin/gb/provider/SimpleExcelExportApp.java
  11. 29
      src/main/java/com/fr/plugin/gb/utils/DLLUtil.java
  12. 145
      src/main/java/com/fr/plugin/gb/utils/InteKeyHandler.java
  13. 9
      src/main/resources/com/fr/plugin/gb/locale/lang.properties
  14. 9
      src/main/resources/com/fr/plugin/gb/locale/lang_zh_CN.properties
  15. BIN
      src/main/resources/win32-x86-64/Encryptor6_64.dll
  16. BIN
      src/main/resources/win32-x86/Encryptor6_32.dll

6
README.md

@ -0,0 +1,6 @@
# open-JSD-10072
JSD-10072 excel解密后导入\
免责说明:该源码为第三方爱好者提供,不保证源码和方案的可靠性,也不提供任何形式的源码教学指导和协助!\
仅作为开发者学习参考使用!禁止用于任何商业用途!\
为保护开发者隐私,开发者信息已隐去!若原开发者希望公开自己的信息,可联系【pioneer】处理。

BIN
lib/finekit-10.0.jar

Binary file not shown.

BIN
lib/jna-4.2.2.jar

Binary file not shown.

BIN
lib/jna-platform-4.2.2.jar

Binary file not shown.

30
plugin.xml

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<plugin>
<id>com.fr.plugin.gb.crypt</id>
<name><![CDATA[导入导出文件加解密_EK]]></name>
<active>yes</active>
<version>1.3.1</version>
<env-version>10.0</env-version>
<jartime>2021-10-01</jartime>
<vendor>fr.open</vendor>
<description><![CDATA[导入导出文件加解密]]></description>
<change-notes><![CDATA[
[2022-04-28]1、FR报表填报预览的导入excel解密;2、FR报表预览的原样导出excel加密。<br/>
[2022-04-28]JSD-10072插件初始化<br/>
]]></change-notes>
<main-package>com.fr.plugin.gb</main-package>
<prefer-packages>
<prefer-package>com.fanruan.api</prefer-package>
<prefer-package>com.sun.jna</prefer-package>
</prefer-packages>
<extra-core>
<LocaleFinder class="com.fr.plugin.gb.LocaleFinder"/>
</extra-core>
<extra-report>
<ExcelExportAppProvider class="com.fr.plugin.gb.provider.SimpleExcelExportApp"/>
</extra-report>
<extra-decision>
<GlobalRequestFilterProvider class="com.fr.plugin.gb.filter.CustomExcelImportDeal"/>
</extra-decision>
<function-recorder class="com.fr.plugin.gb.LocaleFinder"/>
</plugin>

36
src/main/java/com/fr/plugin/gb/LocaleFinder.java

@ -0,0 +1,36 @@
/*
* Copyright (C), 2018-2020
* Project: starter
* FileName: LocaleFinder
* Author: xx
* Date: 2020/8/31 22:19
*/
package com.fr.plugin.gb;
import com.fr.intelli.record.Focus;
import com.fr.intelli.record.Original;
import com.fr.record.analyzer.EnableMetrics;
import com.fr.stable.fun.impl.AbstractLocaleFinder;
/**
* <Function Description><br>
* <LocaleFinder>
*
* @author xx
* @since 1.0.0
*/
@EnableMetrics
public class LocaleFinder extends AbstractLocaleFinder {
public static final String PLUGIN_ID = "com.fr.plugin.gb.crypt";
@Override
@Focus(id = PLUGIN_ID, text = "Plugin-gb", source = Original.PLUGIN)
public String find() {
return "com/fr/plugin/gb/locale/lang";
}
@Override
public int currentAPILevel() {
return CURRENT_LEVEL;
}
}

57
src/main/java/com/fr/plugin/gb/export/ExcelPlusExporter.java

@ -0,0 +1,57 @@
/**
* Copyright (C), 2015-2020
* FileName: ExcelPlusExporter
* Author: xx
* Date: 2020/3/17 11:50
* Description: ExcelPlusExporter
* History:
* <author> <time> <version> <desc>
*/
package com.fr.plugin.gb.export;
import com.fanruan.api.util.StringKit;
import com.fr.io.exporter.ExcelExporter;
import com.fr.main.workbook.ResultWorkBook;
import com.fr.page.PageSetCreator;
import com.fr.plugin.gb.utils.InteKeyHandler;
import com.fr.web.core.ReportRepositoryDeal;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.List;
/**
* Function Description<br>
* ExcelPlusExporter
*
* @author xx
* @since 1.0.0
*/
public class ExcelPlusExporter extends ExcelExporter {
public ExcelPlusExporter() {
}
public ExcelPlusExporter(List list) {
super(list);
}
@Override
public void export(OutputStream outputStream, ResultWorkBook resultWorkBook, PageSetCreator pageSetCreator, ReportRepositoryDeal reportRepositoryDeal, int[] ints) throws Exception {
File file = File.createTempFile("InteKey", StringKit.EMPTY);
FileOutputStream fileOutputStream = new FileOutputStream(file);
super.export(fileOutputStream, resultWorkBook, pageSetCreator, reportRepositoryDeal, ints);
fileOutputStream.close();
InteKeyHandler.getInstance().encryptFile(outputStream, file);
}
@Override
public void export(OutputStream outputStream, ResultWorkBook resultWorkBook) throws Exception {
File file = File.createTempFile("InteKey", StringKit.EMPTY);
FileOutputStream fileOutputStream = new FileOutputStream(file);
super.export(fileOutputStream, resultWorkBook);
fileOutputStream.close();
InteKeyHandler.getInstance().encryptFile(outputStream, file);
}
}

244
src/main/java/com/fr/plugin/gb/filter/BodyRequestWrapper.java

@ -0,0 +1,244 @@
/*
* Copyright (C), 2018-2022
* Project: starter
* FileName: BodyRequestWrapper
* Author: xx
* Date: 2022/5/27 11:39
*/
package com.fr.plugin.gb.filter;
import com.fanruan.api.log.LogKit;
import com.fr.base.ConfigManager;
import com.fr.base.FRContext;
import com.fr.data.NetworkHelper;
import com.fr.general.IOUtils;
import com.fr.general.http.HttpClient;
import com.fr.general.web.ParameterConsts;
import com.fr.plugin.gb.utils.InteKeyHandler;
import com.fr.stable.StringUtils;
import com.fr.web.utils.WebUtils;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;
public class BodyRequestWrapper extends HttpServletRequestWrapper {
private static final int SPEC_HEADER_CHAR = 13;
private byte[] body;
private File file;
private HttpServletRequest m_request;
protected byte m_binArray[];
private int m_totalBytes;
private int m_currentIndex;
private int m_startData;
private int m_endData;
private String fileName;
private String m_boundary = StringUtils.EMPTY;
public BodyRequestWrapper(HttpServletRequest request) {
super(request);
m_request = request;
try {
init();
if (m_startData >= m_endData) {
body = m_binArray;
} else {
file = createNewFile();
byte[] bytes = IOUtils.inputStream2Bytes(new FileInputStream(file));
int fileLen = bytes.length;
int len = m_startData + (m_binArray.length - m_endData - 1) + bytes.length;
body = new byte[len];
for (int i = 0, j = m_endData + 1; i < len; i++) {
if (i < m_startData) {
body[i] = m_binArray[i];
} else if (i >= m_startData && (i - m_startData <= fileLen - 1)) {
body[i] = bytes[i - m_startData];
} else {
body[i] = m_binArray[j];
j++;
}
}
}
} catch (Exception e) {
LogKit.error(e.getMessage(), e);
}
}
@Override
public ServletInputStream getInputStream() throws IOException {
try {
final ByteArrayInputStream localByteArrayInputStream = new ByteArrayInputStream(this.body);
return new ServletInputStream() {
@Override
public int read() throws IOException {
return localByteArrayInputStream.read();
}
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
}
};
} catch (Exception e) {
e.printStackTrace();
}
return super.getInputStream();
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(getInputStream()));
}
public File createNewFile() {
byte[] var1 = new byte[this.m_endData - this.m_startData + 1];
System.arraycopy(this.m_binArray, this.m_startData, var1, 0, var1.length);
return InteKeyHandler.getInstance().decrypt(new ByteArrayInputStream(var1));
}
/**
* 初始化方法
* 里面的方法都是从smartUpload里面copy出来的
* 主要是为了找出输入流中 真正的关于文件的部分吧这个部分替换掉
*/
public void init() {
int i = 0;
boolean flag1 = false;
long length = 0;
m_totalBytes = m_request.getContentLength();
if (m_totalBytes < 0) {
return;
}
if (WebUtils.getHTTPRequestParameter(m_request, ParameterConsts.REDIRECT_FROM) != null) {
//从HttpClient里再捞一把, 因为有可能是集群转发作为正文传过来的.
InputStream in = HttpClient.getInputStream(m_request);
m_binArray = IOUtils.inputStream2Bytes(in);
} else {
InputStream in = NetworkHelper.getRequestInputStream(m_request);
m_binArray = IOUtils.inputStream2Bytes(in);
}
for (; !flag1 && m_currentIndex < m_totalBytes; m_currentIndex++) {
if (m_binArray[m_currentIndex] == SPEC_HEADER_CHAR) {
flag1 = true;
} else {
m_boundary = m_boundary + (char) m_binArray[m_currentIndex];
}
}
if (m_currentIndex == 1) {
return;
}
m_currentIndex++;
String header = getDataHeader();
String pathName = getDataFieldValue(header, "filename");
fileName = getFileName(pathName);
m_currentIndex = m_currentIndex + 2;
getDataSection();
}
@Override
protected void finalize() throws Throwable {
super.finalize();
// if (file != null) {
// file.delete();
// }
}
private String getDataHeader() {
// boolean flag = false;
int i = m_currentIndex;
int j = 0;
for (boolean flag1 = false; !flag1; ) {
if (m_binArray[m_currentIndex] == SPEC_HEADER_CHAR && m_binArray[m_currentIndex + 2] == SPEC_HEADER_CHAR) {
flag1 = true;
j = m_currentIndex - 1;
m_currentIndex = m_currentIndex + 2;
} else {
m_currentIndex++;
}
}
String header = StringUtils.EMPTY;
try {
// 字符编码要与服务器端设置的保持一致
header = new String(m_binArray, i, (j - i) + 1, ConfigManager.getProviderInstance().getServerCharset());
} catch (UnsupportedEncodingException e) {
FRContext.getLogger().error(e.getMessage());
}
return header;
}
private void getDataSection() {
// boolean flag = false;
// String s = "";
// String s = new String();
int i = m_currentIndex;
int j = 0;
int k = m_boundary.length();
m_startData = m_currentIndex;
m_endData = 0;
while (i < m_totalBytes) {
if (m_binArray[i] == (byte) m_boundary.charAt(j)) {
if (j == k - 1) {
m_endData = ((i - k) + 1) - 3;
break;
}
i++;
j++;
} else {
i++;
j = 0;
}
}
m_currentIndex = m_endData + k + 3;
}
private String getDataFieldValue(String s, String s1) {
String s2 = ""; // = new String();
String s3 = ""; // = new String();
int i = 0;
// boolean flag = false;
// boolean flag1 = false;
// boolean flag2 = false;
s2 = s1 + "=" + '"';
i = s.indexOf(s2);
if (i > 0) {
int j = i + s2.length();
int k = j;
s2 = "\"";
int l = s.indexOf(s2, j);
if (k > 0 && l > 0) {
s3 = s.substring(k, l);
}
}
return s3;
}
private String getFileName(String fileName) {
int i = 0;
i = fileName.lastIndexOf('/');
if (i != -1) {
return fileName.substring(i + 1, fileName.length());
}
i = fileName.lastIndexOf('\\');
if (i != -1) {
return fileName.substring(i + 1, fileName.length());
} else {
return fileName;
}
}
}

45
src/main/java/com/fr/plugin/gb/filter/CustomExcelImportDeal.java

@ -0,0 +1,45 @@
/*
* Copyright (C), 2018-2022
* Project: starter
* FileName: CustomExcelImportDeal
* Author: xx
* Date: 2022/5/27 11:39
*/
package com.fr.plugin.gb.filter;
import com.fanruan.api.log.LogKit;
import com.fanruan.api.util.StringKit;
import com.fr.decision.fun.impl.AbstractGlobalRequestFilterProvider;
import com.fr.web.utils.WebUtils;
import javax.servlet.FilterChain;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class CustomExcelImportDeal extends AbstractGlobalRequestFilterProvider {
@Override
public String filterName() {
return "importExcel";
}
@Override
public String[] urlPatterns() {
return new String[]{"/decision/view/report"};
}
@Override
public void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain filterChain) {
try {
String op = WebUtils.getHTTPRequestParameter(req, "op");
String cmd = WebUtils.getHTTPRequestParameter(req, "cmd");
if (StringKit.equals(op, "fr_write") && StringKit.equals(cmd, "imp_w_excel_data")) {
filterChain.doFilter(new BodyRequestWrapper(req), res);
} else {
filterChain.doFilter(req, res);
}
} catch (Exception e) {
LogKit.error(e.getMessage(), e);
}
}
}

45
src/main/java/com/fr/plugin/gb/provider/SimpleExcelExportApp.java

@ -0,0 +1,45 @@
/*
* Copyright (C), 2018-2021
* Project: starter
* FileName: SimpleExcelExportApp
* Author: xx
* Date: 2021/12/6 8:27
*/
package com.fr.plugin.gb.provider;
import com.fr.general.ReportDeclareRecordType;
import com.fr.io.collection.ExportCollection;
import com.fr.io.exporter.AppExporter;
import com.fr.io.exporter.ExcelExportType;
import com.fr.plugin.gb.export.ExcelPlusExporter;
import com.fr.report.core.ReportUtils;
import com.fr.report.fun.impl.AbstractExcelExportAppProvider;
import com.fr.stable.ExportConstants;
import com.fr.stable.fun.Authorize;
import com.fr.stable.web.SessionProvider;
import static com.fr.plugin.gb.LocaleFinder.PLUGIN_ID;
/**
* <Function Description><br>
* <原样导出SimpleExcelExportApp>
*
* @author xx
* @since 1.0.0
*/
@Authorize(callSignKey = PLUGIN_ID)
public class SimpleExcelExportApp extends AbstractExcelExportAppProvider {
@Override
public String exportType() {
return ExportConstants.TYPE_SIMPLE;
}
@Override
public AppExporter<Boolean> newAppExporter(ExportCollection collection, ExcelExportType exportType, SessionProvider sessionIDInfor) {
AppExporter<Boolean> exporter = new ExcelPlusExporter(ReportUtils.getPaperSettingListFromWorkBook(sessionIDInfor.getOriginalObject()));
collection.setExporter(exporter);
collection.setRecordType(ReportDeclareRecordType.EXPORT_TYPE_EXCEL_ORIGINAL);
return exporter;
}
}

29
src/main/java/com/fr/plugin/gb/utils/DLLUtil.java

@ -0,0 +1,29 @@
/*
* Copyright (C), 2018-2022
* Project: starter
* FileName: DLLUtil
* Author: xx
* Date: 2022/5/10 16:39
*/
package com.fr.plugin.gb.utils;
import com.sun.jna.Library;
import com.sun.jna.Native;
/**
* <Function Description><br>
* <DLLUtil>
*
* @author xx
* @since 1.0.0
*/
public interface DLLUtil extends Library {
// DLLUtil dllUtil32 = (DLLUtil) Native.load("Encryptor6_32.dll", DLLUtil.class);
DLLUtil dllUtil64 = (DLLUtil) Native.loadLibrary("Encryptor6_64.dll", DLLUtil.class);
public int Da(String strFilePath, int bReplace, String dstFilePath);
public int Ia(String pFilePath);
public int Ea(String strFilePath);
}

145
src/main/java/com/fr/plugin/gb/utils/InteKeyHandler.java

@ -0,0 +1,145 @@
/*
* Copyright (C), 2018-2022
* Project: starter
* FileName: InteKeyHandler
* Author: xx
* Date: 2022/3/7 11:19
*/
package com.fr.plugin.gb.utils;
import com.fanruan.api.i18n.I18nKit;
import com.fanruan.api.log.LogKit;
import com.fanruan.api.util.IOKit;
import com.fanruan.api.util.StringKit;
import com.fr.general.ComparatorUtils;
import com.fr.plugin.context.PluginContexts;
import java.io.*;
/**
* <Function Description><br>
* <InteKeyHandler>
*
* @author xx
* @since 1.0.0
*/
public class InteKeyHandler {
private static volatile InteKeyHandler handler = null;
public InteKeyHandler() {
}
public static InteKeyHandler getInstance() {
if (handler == null) {
handler = new InteKeyHandler();
}
return handler;
}
/**
* 加密文件操作
*
* @param out
* @param file
*/
public void encryptFile(OutputStream out, File file) {
if (PluginContexts.currentContext() == null || !PluginContexts.currentContext().isAvailable()) {
LogKit.error(I18nKit.getLocText("Plugin-gb_Licence_Expired"));
return;
}
LogKit.info("gb-InteKeyHandler-encryptFile-filePath:{}", file.getAbsolutePath());
if (!encrypt(file.getAbsolutePath())) {
return;
}
try {
FileInputStream in = new FileInputStream(file);
byte[] b = new byte[1024];
int len;
while ((len = in.read(b)) != -1) {
out.write(b, 0, len);
}
out.close();
in.close();
} catch (IOException e) {
LogKit.error(e.getMessage(), e);
}
}
/**
* 输入流解密操作
*
* @param inputStream
* @return
*/
public File decrypt(InputStream inputStream) {
if (PluginContexts.currentContext() == null || !PluginContexts.currentContext().isAvailable()) {
LogKit.error(I18nKit.getLocText("Plugin-gb_Licence_Expired"));
return null;
}
byte[] bytes = IOKit.inputStream2Bytes(inputStream);
FileOutputStream fos = null;
File tempFile = null;
try {
tempFile = File.createTempFile("InteKey", StringKit.EMPTY);
fos = new FileOutputStream(tempFile);
fos.write(bytes);
//流关闭,指针null,目的是为了解密的时候这个程序这边不占用,要不然解密的时候会报错,文件被其他文件占用
fos.flush();
fos.close();
fos = null;
String filePath = tempFile.getAbsolutePath();
tempFile = null;
LogKit.info("gb-InteKeyHandler-decrypt-filePath:{}", filePath);
if (!isEncryptFile(filePath)) {
LogKit.info("gb-InteKeyHandler-decrypt-Not Encrypt File");
return new File(filePath);
}
if (!decrypt(filePath)) {
LogKit.info("gb-InteKeyHandler-decrypt-File decrypt failed");
return new File(filePath);
}
LogKit.info("gb-InteKeyHandler-decrypt-FileInputStream");
return new File(filePath);
} catch (Exception e) {
LogKit.error(e.getMessage(), e);
return null;
}
}
public boolean encrypt(String path) {
System.setProperty("jna.encoding", "GBK");
int resultCode;
resultCode = DLLUtil.dllUtil64.Ea(path);
LogKit.info("gb-InteKeyHandler-encrypt-resultCode:{}", resultCode);
return ComparatorUtils.equals(resultCode, 0);
// return true;
}
public boolean decrypt(String path) {
int resultCode = -1;
int index = 0;
while (true) {
if (!ComparatorUtils.equals(DLLUtil.dllUtil64.Ia(path), 0)) {
resultCode = DLLUtil.dllUtil64.Da(path, 1, "");
} else {
break;
}
index++;
if (index > 20) {
break;
}
}
LogKit.info("gb-InteKeyHandler-decrypt-resultCode:{}", resultCode);
return ComparatorUtils.equals(resultCode, 0);
// return true;
}
public boolean isEncryptFile(String path) {
System.setProperty("jna.encoding", "GBK");
int resultCode;
resultCode = DLLUtil.dllUtil64.Ia(path);
LogKit.info("gb-InteKeyHandler-isEncryptFile-resultCode:{}", resultCode);
return ComparatorUtils.equals(resultCode, 1) || ComparatorUtils.equals(resultCode, 2);
// return true;
}
}

9
src/main/resources/com/fr/plugin/gb/locale/lang.properties

@ -0,0 +1,9 @@
Plugin-gb=File Crypt Plugin
Plugin-gb_Group=File Crypt Plugin
Plugin-gb_Config_KeyID=KeyID
Plugin-gb_Config_KeyID_Description=KeyID
Plugin-gb_Config_KeyLevel=KeyLevel
Plugin-gb_Config_KeyLevel_Description=KeyLevel
Plugin-gb_Config_UserDir=UserDir
Plugin-gb_Config_UserDir_Description=UserDir
Plugin-gb_Licence_Expired=File Crypt Plugin Licence Expired

9
src/main/resources/com/fr/plugin/gb/locale/lang_zh_CN.properties

@ -0,0 +1,9 @@
Plugin-gb=\u5BFC\u5165\u5BFC\u51FA\u6587\u4EF6\u52A0\u89E3\u5BC6
Plugin-gb_Group=\u5BFC\u5165\u5BFC\u51FA\u6587\u4EF6\u52A0\u89E3\u5BC6\u63D2\u4EF6
Plugin-gb_Config_KeyID=\u79D8\u94A5
Plugin-gb_Config_KeyID_Description=\u79D8\u94A5
Plugin-gb_Config_KeyLevel=\u5BC6\u7EA7
Plugin-gb_Config_KeyLevel_Description=\u5BC6\u7EA7
Plugin-gb_Config_UserDir=\u63A5\u53E3\u76EE\u5F55
Plugin-gb_Config_UserDir_Description=\u63A5\u53E3\u76EE\u5F55
Plugin-gb_Licence_Expired=\u5BFC\u5165\u5BFC\u51FA\u6587\u4EF6\u52A0\u89E3\u5BC6\u63D2\u4EF6\u8BB8\u53EF\u8FC7\u671F

BIN
src/main/resources/win32-x86-64/Encryptor6_64.dll

Binary file not shown.

BIN
src/main/resources/win32-x86/Encryptor6_32.dll

Binary file not shown.
Loading…
Cancel
Save