feat: v0.4.0, decrypt and edit tinyenc

This commit is contained in:
2022-04-17 16:26:26 +08:00
parent 7cebbfddaa
commit f0e521142f
5 changed files with 60 additions and 26 deletions

View File

@@ -19,6 +19,9 @@ public class TinyEncryptArgs {
@CommandLine.Option(names = {"-s", "--show"}, description = "Show decrypted text in window") @CommandLine.Option(names = {"-s", "--show"}, description = "Show decrypted text in window")
boolean showInWindow = false; boolean showInWindow = false;
@CommandLine.Option(names = {"-t", "--edit"}, description = "Edit decrypted text in window")
boolean editInWindow = false;
@CommandLine.Option(names = {"-k", "--key"}, description = "Encrypt KMS key") @CommandLine.Option(names = {"-k", "--key"}, description = "Encrypt KMS key")
String key; String key;

View File

@@ -78,8 +78,8 @@ public class TinyEncryptMain {
tinyEncryptArgs.compress, !tinyEncryptArgs.skipEnvelop, tinyEncryptArgs.requireSign, tinyEncryptArgs.compress, !tinyEncryptArgs.skipEnvelop, tinyEncryptArgs.requireSign,
tinyEncryptArgs.comment, tinyEncryptArgs.encryptedComment); tinyEncryptArgs.comment, tinyEncryptArgs.encryptedComment);
} else { } else {
if (tinyEncryptArgs.showInWindow) { if (tinyEncryptArgs.showInWindow || tinyEncryptArgs.editInWindow) {
EncryptedFileUtil.decryptInWindow(config, f, tinyEncryptArgs.pgp); EncryptedFileUtil.decryptInWindow(config, f, tinyEncryptArgs.pgp, tinyEncryptArgs.editInWindow);
decryptSuccess = false; // do not delete file decryptSuccess = false; // do not delete file
} else if (tinyEncryptArgs.digest) { } else if (tinyEncryptArgs.digest) {
Bytes sha256 = EncryptedFileUtil.decryptAndDigest(config, f, tinyEncryptArgs.pgp); Bytes sha256 = EncryptedFileUtil.decryptAndDigest(config, f, tinyEncryptArgs.pgp);

View File

@@ -133,7 +133,7 @@ public class TinyEncryptMainUtil {
sb.append("\n"); sb.append("\n");
} }
sb.append(header("Enc file summary")).append("Version: ").append(meta.getVersion()) sb.append(header("Enc file summary")).append("Version: ").append(meta.getVersion())
.append(", Agent").append(meta.getUserAgent()) .append(", Agent: ").append(meta.getUserAgent())
.append("\n"); .append("\n");
if (meta.getFileLastModified() != null) { if (meta.getFileLastModified() != null) {
sb.append(header("Last modified")).append(new Date(meta.getFileLastModified())).append("\n"); sb.append(header("Last modified")).append(new Date(meta.getFileLastModified())).append("\n");

View File

@@ -1,7 +1,7 @@
package me.hatter.tools.tinyencrypt.config; package me.hatter.tools.tinyencrypt.config;
public class TinyEncryptConstant { public class TinyEncryptConstant {
public static final String VERSION = "0.3.14"; public static final String VERSION = "0.4.0";
public static final String ENC_FILE_EXT = ".tinyenc"; public static final String ENC_FILE_EXT = ".tinyenc";
} }

View File

@@ -24,13 +24,14 @@ import me.hatter.tools.tinyencrypt.util.SwingWindow;
import java.io.*; import java.io.*;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream; import java.util.zip.GZIPOutputStream;
public class EncryptedFileUtil { public class EncryptedFileUtil {
private static final LogTool log = LogTools.getLogTool(EncryptedFileUtil.class); private static final LogTool log = LogTools.getLogTool(EncryptedFileUtil.class);
public static boolean decryptToOutputStream(TinyEncryptConfig config, File file, OutputStream os, boolean pgp) { public static boolean decryptToOutputStream(TinyEncryptConfig config, File file, OutputStream os, boolean pgp, AtomicReference<TinyEncryptMeta> metaRef) {
if (getDecryptFile(file) == null) { if (getDecryptFile(file) == null) {
log.warn("File is not tinyenc file, skip: " + file); log.warn("File is not tinyenc file, skip: " + file);
return false; return false;
@@ -39,6 +40,9 @@ public class EncryptedFileUtil {
try (FileInputStream fis = new FileInputStream(file)) { try (FileInputStream fis = new FileInputStream(file)) {
Tlv tlv = TlvUtil.readTlv(fis); Tlv tlv = TlvUtil.readTlv(fis);
TinyEncryptMeta meta = tlv.getValueAsBytes().asJSONObject(TinyEncryptMeta.class); TinyEncryptMeta meta = tlv.getValueAsBytes().asJSONObject(TinyEncryptMeta.class);
if (metaRef != null) {
metaRef.set(meta);
}
byte[] dataKey; byte[] dataKey;
if (pgp) { if (pgp) {
@@ -99,19 +103,43 @@ public class EncryptedFileUtil {
public static Bytes decryptAndDigest(TinyEncryptConfig config, File file, boolean pgp) { public static Bytes decryptAndDigest(TinyEncryptConfig config, File file, boolean pgp) {
DigestOutputStream outputStream = new DigestOutputStream(new NilOutputStream(), Digests.sha256()); DigestOutputStream outputStream = new DigestOutputStream(new NilOutputStream(), Digests.sha256());
if (!decryptToOutputStream(config, file, outputStream, pgp)) { if (!decryptToOutputStream(config, file, outputStream, pgp, null)) {
return null; return null;
} }
return outputStream.digest(); return outputStream.digest();
} }
public static void decryptInWindow(TinyEncryptConfig config, File file, boolean pgp) { public static void decryptInWindow(TinyEncryptConfig config, File file, boolean pgp, boolean editable) {
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
decryptToOutputStream(config, file, baos, pgp); AtomicReference<TinyEncryptMeta> metaRef = new AtomicReference<>();
SwingWindow.create("Decrypted file: " + file.getName()) decryptToOutputStream(config, file, baos, pgp, metaRef);
String decrypted = new String(baos.toByteArray(), StandardCharsets.UTF_8);
String editResult = SwingWindow.create((editable ? "Edit" : "View") + " file: " + file.getName())
.message("File: " + file) .message("File: " + file)
.text(new String(baos.toByteArray(), StandardCharsets.UTF_8)) .text(decrypted)
.editable(editable)
.show().getResult(); .show().getResult();
if (editable) {
if (editResult == null) {
log.warn("You cancel the edit operation");
} else if (editResult.equals(decrypted)) {
log.warn("Text is not modified");
} else {
log.debug("Write to encrypt file: " + file);
byte[] bytes = editResult.getBytes(StandardCharsets.UTF_8);
InputStream inputStream = new ByteArrayInputStream(bytes);
try {
TinyEncryptMeta meta = metaRef.get();
meta.setFileLength((long) bytes.length);
meta.setFileLastModified(System.currentTimeMillis());
encryptFromInputStream(inputStream, file, meta);
log.info("Write to encrypt file: " + file + " success");
} catch (IOException e) {
log.error("Write to encrypt file: " + file + " failed", e);
}
}
}
} }
public static boolean decryptFile(TinyEncryptConfig config, File file, boolean pgp) { public static boolean decryptFile(TinyEncryptConfig config, File file, boolean pgp) {
@@ -127,7 +155,7 @@ public class EncryptedFileUtil {
try { try {
boolean decryptResult; boolean decryptResult;
try (FileOutputStream fos = new FileOutputStream(decFile)) { try (FileOutputStream fos = new FileOutputStream(decFile)) {
decryptResult = decryptToOutputStream(config, file, fos, pgp); decryptResult = decryptToOutputStream(config, file, fos, pgp, null);
} }
if (!decryptResult) { if (!decryptResult) {
if (decFile.length() == 0) { if (decFile.length() == 0) {
@@ -164,22 +192,8 @@ public class EncryptedFileUtil {
meta.setFileLength(file.length()); meta.setFileLength(file.length());
meta.setFileLastModified(file.lastModified()); meta.setFileLastModified(file.lastModified());
meta.setCompress(compress); meta.setCompress(compress);
Tlv tlv = TlvUtil.create(1, TinyEncryptMetaUtil.toString(meta));
try (FileInputStream fis = new FileInputStream(file)) { try (FileInputStream fis = new FileInputStream(file)) {
try (FileOutputStream fos = new FileOutputStream(encFile)) { encryptFromInputStream(fis, encFile, meta);
TlvUtil.writeTlv(fos, tlv);
fos.flush();
try (OutputStream newOs = getEncryptOutputStream(fos, meta)) {
if (compress) {
GZIPOutputStream gzOs = new GZIPOutputStream(newOs);
IOUtil.copy(fis, gzOs, new DefaultRollCounter().prefix("Encrypting, "));
gzOs.finish();
} else {
IOUtil.copy(fis, newOs, new DefaultRollCounter().prefix("Encrypting, "));
}
}
}
} }
log.info("Encrypt file success: " + file); log.info("Encrypt file success: " + file);
return true; return true;
@@ -190,6 +204,23 @@ public class EncryptedFileUtil {
} }
} }
private static void encryptFromInputStream(InputStream inputStream, File encFile, TinyEncryptMeta meta) throws IOException {
Tlv tlv = TlvUtil.create(1, TinyEncryptMetaUtil.toString(meta));
try (FileOutputStream fos = new FileOutputStream(encFile)) {
TlvUtil.writeTlv(fos, tlv);
fos.flush();
try (OutputStream newOs = getEncryptOutputStream(fos, meta)) {
if ((meta.getCompress() != null) && meta.getCompress()) {
GZIPOutputStream gzOs = new GZIPOutputStream(newOs);
IOUtil.copy(inputStream, gzOs, new DefaultRollCounter().prefix("Encrypting, "));
gzOs.finish();
} else {
IOUtil.copy(inputStream, newOs, new DefaultRollCounter().prefix("Encrypting, "));
}
}
}
}
public static File getEncryptFile(File file) { public static File getEncryptFile(File file) {
File absFile = file.getAbsoluteFile(); File absFile = file.getAbsoluteFile();
if (absFile.getName().endsWith(TinyEncryptConstant.ENC_FILE_EXT)) { if (absFile.getName().endsWith(TinyEncryptConstant.ENC_FILE_EXT)) {