You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
190 lines
6.9 KiB
190 lines
6.9 KiB
package com.fr.plugin.xx.zyjn.decode.encode; |
|
|
|
import cn.net.drm.edi.client.DrmAgent; |
|
import cn.net.drm.edi.client.DrmAgentInf; |
|
import cn.net.drm.io.IOUtils; |
|
import com.fr.general.CommonIOUtils; |
|
import com.fr.plugin.xx.zyjn.decode.DecodeConfig; |
|
import com.fr.plugin.xx.zyjn.decode.LogUtils; |
|
import com.fr.plugin.xx.zyjn.decode.encode.bi.FileUtil; |
|
import org.apache.tools.zip.ZipOutputStream; |
|
|
|
import javax.servlet.ServletOutputStream; |
|
import javax.servlet.WriteListener; |
|
import java.io.*; |
|
import java.util.UUID; |
|
import java.util.stream.Collectors; |
|
import java.util.stream.Stream; |
|
|
|
/** |
|
* @Author xx |
|
* @Date 2022/3/3 |
|
* @Description |
|
**/ |
|
public class EncryptOutputStream extends ServletOutputStream { |
|
|
|
private OutputStream original = null; |
|
private boolean closed = false; |
|
private ByteArrayOutputStream crypt = new ByteArrayOutputStream(); |
|
|
|
public EncryptOutputStream(OutputStream original) { |
|
this.original = original; |
|
} |
|
|
|
/** |
|
* 实际加密的代码就在这里实现了 |
|
* |
|
* @param bytes |
|
* @param ignore |
|
* @return |
|
*/ |
|
public static byte[] encrypt(byte[] bytes, boolean ignore) { |
|
DecodeConfig config = DecodeConfig.getInstance(); |
|
/*if (!config.isConfiged()) { |
|
LogUtils.warn("config not finish, not encrypted"); |
|
return bytes; |
|
}*/ |
|
ByteArrayInputStream bis = new ByteArrayInputStream(bytes); |
|
byte[] header = new byte[256]; |
|
bis.mark(256); |
|
byte[] encode = bytes; |
|
OutputStream fos = null; |
|
try { |
|
DrmAgentInf instance = null; |
|
instance = DrmAgent.getInstance(); |
|
File tempFile = File.createTempFile("tmp" + UUID.randomUUID().toString(), null); |
|
LogUtils.info("create tmp file path is {}", tempFile.getPath()); |
|
bis.read(header); |
|
bis.reset(); |
|
boolean isEncryptFile = instance.isEncrypted(tempFile); |
|
if (!isEncryptFile) { |
|
if (FileUtil.isArchiveFile(bytes) && !ignore) { |
|
encode = encodeZip(bytes, instance, config); |
|
} else { |
|
//fos = instance.encryptBasicFile(tempFile, config.getOwnerId(), config.getSecretLevelId()); |
|
int len = 0; |
|
byte[] buffer = new byte[1024]; |
|
while ((len = bis.read(buffer)) > 0) { |
|
fos.write(buffer, 0, len); |
|
} |
|
fos.flush(); |
|
FileInputStream in = new FileInputStream(tempFile); |
|
encode = CommonIOUtils.inputStream2Bytes(in); |
|
tempFile.deleteOnExit(); |
|
} |
|
} |
|
} catch (Exception e) { |
|
LogUtils.error(e.getMessage(), e); |
|
} finally { |
|
IOUtils.closeQuietly(bis); |
|
IOUtils.closeQuietly(fos); |
|
|
|
} |
|
//假设逆序就是加密了 |
|
return encode; |
|
} |
|
|
|
private static byte[] encodeZip(byte[] bytes, DrmAgentInf instance, DecodeConfig config) { |
|
File zipFile = null, encodeZipFile = null; |
|
File unzipFileFolder = FileUtil.createTempFolder("tmp_unzip" + UUID.randomUUID().toString()); |
|
File zipFileFolder = FileUtil.createTempFolder("tmp_zip" + UUID.randomUUID().toString()); |
|
try { |
|
encodeZipFile = FileUtil.createTempFile(); |
|
zipFile = FileUtil.createTempFile(); |
|
//先缓存文件 |
|
com.fr.general.IOUtils.copyBinaryTo(new ByteArrayInputStream(bytes), new FileOutputStream(zipFile)); |
|
LogUtils.debug4plugin("save zip file path:{} size is {}", zipFile.getAbsolutePath(), zipFile.getTotalSpace()); |
|
//再解压出来 |
|
com.fr.general.IOUtils.unzip(zipFile, unzipFileFolder.getAbsolutePath(),"GBK"); |
|
LogUtils.debug4plugin("unzip file path is {} file list is {} unzip size is {}", unzipFileFolder.getAbsolutePath(), Stream.of(unzipFileFolder.listFiles()).map(e->e.getName()).collect(Collectors.joining(",")), unzipFileFolder.listFiles().length); |
|
File[] files = unzipFileFolder.listFiles(); |
|
ZipOutputStream zipOutputStream = new ZipOutputStream(encodeZipFile); |
|
zipOutputStream.setEncoding("GBK"); |
|
for (int i = 0; i < files.length; i++) { |
|
File file = files[i]; |
|
//加密复制到另外一个文件夹 |
|
String encode = zipFileFolder + File.separator + file.getName(); |
|
InputStream bis = new FileInputStream(file); |
|
//加密 |
|
OutputStream fos =null;// instance.encryptBasicStream(new FileOutputStream(encode), config.getOwnerId(), config.getSecretLevelId()); |
|
int len = 0; |
|
byte[] buffer = new byte[1024]; |
|
while ((len = bis.read(buffer)) > 0) { |
|
fos.write(buffer, 0, len); |
|
} |
|
fos.flush(); |
|
IOUtils.closeQuietly(bis); |
|
IOUtils.closeQuietly(fos); |
|
LogUtils.debug4plugin("encode file {} to {}", file.getAbsolutePath(), encode); |
|
} |
|
//zip |
|
com.fr.general.IOUtils.zip(zipOutputStream, zipFileFolder); |
|
zipOutputStream.closeEntry(); |
|
zipOutputStream.close(); |
|
LogUtils.debug4plugin("zip file folder {} to {}", zipFileFolder, encodeZipFile.getAbsolutePath()); |
|
bytes = CommonIOUtils.inputStream2Bytes(new FileInputStream(encodeZipFile)); |
|
} catch (Exception e) { |
|
LogUtils.error(e.getMessage(), e); |
|
} finally { |
|
if (zipFile != null) { |
|
zipFile.deleteOnExit(); |
|
} |
|
if (encodeZipFile != null) { |
|
encodeZipFile.deleteOnExit(); |
|
} |
|
unzipFileFolder.deleteOnExit(); |
|
zipFileFolder.deleteOnExit(); |
|
zipFile.deleteOnExit(); |
|
} |
|
return bytes; |
|
} |
|
|
|
@Override |
|
public void write(int b) throws IOException { |
|
if (closed) { |
|
throw new IOException("Cannot write to a closed output stream"); |
|
} |
|
crypt.write(b); |
|
} |
|
|
|
@Override |
|
public void close() throws IOException { |
|
if (!closed) { |
|
byte[] bytes = crypt.toByteArray(); |
|
bytes = encrypt(bytes, false); |
|
original.write(bytes); |
|
original.flush(); |
|
original.close(); |
|
closed = true; |
|
} |
|
} |
|
|
|
@Override |
|
public void flush() throws IOException { |
|
crypt.flush(); |
|
} |
|
|
|
@Override |
|
public void write(byte[] data) throws IOException { |
|
write(data, 0, data.length); |
|
} |
|
|
|
@Override |
|
public void write(byte[] data, int off, int len) throws IOException { |
|
if (closed) { |
|
throw new IOException("Cannot write to a closed output stream"); |
|
} |
|
crypt.write(data, off, len); |
|
} |
|
|
|
@Override |
|
public boolean isReady() { |
|
return true; |
|
} |
|
|
|
@Override |
|
public void setWriteListener(WriteListener listener) { |
|
|
|
} |
|
|
|
}
|
|
|