From f0e521142f173e0367ebc6b997a97b1675437fa8 Mon Sep 17 00:00:00 2001 From: Hatter Jiang Date: Sun, 17 Apr 2022 16:26:26 +0800 Subject: [PATCH] feat: v0.4.0, decrypt and edit tinyenc --- .../tools/tinyencrypt/TinyEncryptArgs.java | 3 + .../tools/tinyencrypt/TinyEncryptMain.java | 4 +- .../tinyencrypt/TinyEncryptMainUtil.java | 2 +- .../config/TinyEncryptConstant.java | 2 +- .../encrypt/EncryptedFileUtil.java | 75 +++++++++++++------ 5 files changed, 60 insertions(+), 26 deletions(-) diff --git a/src/main/java/me/hatter/tools/tinyencrypt/TinyEncryptArgs.java b/src/main/java/me/hatter/tools/tinyencrypt/TinyEncryptArgs.java index e1931b8..80caa74 100644 --- a/src/main/java/me/hatter/tools/tinyencrypt/TinyEncryptArgs.java +++ b/src/main/java/me/hatter/tools/tinyencrypt/TinyEncryptArgs.java @@ -19,6 +19,9 @@ public class TinyEncryptArgs { @CommandLine.Option(names = {"-s", "--show"}, description = "Show decrypted text in window") 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") String key; diff --git a/src/main/java/me/hatter/tools/tinyencrypt/TinyEncryptMain.java b/src/main/java/me/hatter/tools/tinyencrypt/TinyEncryptMain.java index f0bdc37..3358fa1 100644 --- a/src/main/java/me/hatter/tools/tinyencrypt/TinyEncryptMain.java +++ b/src/main/java/me/hatter/tools/tinyencrypt/TinyEncryptMain.java @@ -78,8 +78,8 @@ public class TinyEncryptMain { tinyEncryptArgs.compress, !tinyEncryptArgs.skipEnvelop, tinyEncryptArgs.requireSign, tinyEncryptArgs.comment, tinyEncryptArgs.encryptedComment); } else { - if (tinyEncryptArgs.showInWindow) { - EncryptedFileUtil.decryptInWindow(config, f, tinyEncryptArgs.pgp); + if (tinyEncryptArgs.showInWindow || tinyEncryptArgs.editInWindow) { + EncryptedFileUtil.decryptInWindow(config, f, tinyEncryptArgs.pgp, tinyEncryptArgs.editInWindow); decryptSuccess = false; // do not delete file } else if (tinyEncryptArgs.digest) { Bytes sha256 = EncryptedFileUtil.decryptAndDigest(config, f, tinyEncryptArgs.pgp); diff --git a/src/main/java/me/hatter/tools/tinyencrypt/TinyEncryptMainUtil.java b/src/main/java/me/hatter/tools/tinyencrypt/TinyEncryptMainUtil.java index 796237a..f772ae3 100644 --- a/src/main/java/me/hatter/tools/tinyencrypt/TinyEncryptMainUtil.java +++ b/src/main/java/me/hatter/tools/tinyencrypt/TinyEncryptMainUtil.java @@ -133,7 +133,7 @@ public class TinyEncryptMainUtil { sb.append("\n"); } sb.append(header("Enc file summary")).append("Version: ").append(meta.getVersion()) - .append(", Agent").append(meta.getUserAgent()) + .append(", Agent: ").append(meta.getUserAgent()) .append("\n"); if (meta.getFileLastModified() != null) { sb.append(header("Last modified")).append(new Date(meta.getFileLastModified())).append("\n"); diff --git a/src/main/java/me/hatter/tools/tinyencrypt/config/TinyEncryptConstant.java b/src/main/java/me/hatter/tools/tinyencrypt/config/TinyEncryptConstant.java index 3bfe97a..114533c 100644 --- a/src/main/java/me/hatter/tools/tinyencrypt/config/TinyEncryptConstant.java +++ b/src/main/java/me/hatter/tools/tinyencrypt/config/TinyEncryptConstant.java @@ -1,7 +1,7 @@ package me.hatter.tools.tinyencrypt.config; 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"; } diff --git a/src/main/java/me/hatter/tools/tinyencrypt/encrypt/EncryptedFileUtil.java b/src/main/java/me/hatter/tools/tinyencrypt/encrypt/EncryptedFileUtil.java index b3735c1..8bb5359 100644 --- a/src/main/java/me/hatter/tools/tinyencrypt/encrypt/EncryptedFileUtil.java +++ b/src/main/java/me/hatter/tools/tinyencrypt/encrypt/EncryptedFileUtil.java @@ -24,13 +24,14 @@ import me.hatter.tools.tinyencrypt.util.SwingWindow; import java.io.*; import java.nio.charset.StandardCharsets; import java.util.Optional; +import java.util.concurrent.atomic.AtomicReference; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; public class EncryptedFileUtil { 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 metaRef) { if (getDecryptFile(file) == null) { log.warn("File is not tinyenc file, skip: " + file); return false; @@ -39,6 +40,9 @@ public class EncryptedFileUtil { try (FileInputStream fis = new FileInputStream(file)) { Tlv tlv = TlvUtil.readTlv(fis); TinyEncryptMeta meta = tlv.getValueAsBytes().asJSONObject(TinyEncryptMeta.class); + if (metaRef != null) { + metaRef.set(meta); + } byte[] dataKey; if (pgp) { @@ -99,19 +103,43 @@ public class EncryptedFileUtil { public static Bytes decryptAndDigest(TinyEncryptConfig config, File file, boolean pgp) { DigestOutputStream outputStream = new DigestOutputStream(new NilOutputStream(), Digests.sha256()); - if (!decryptToOutputStream(config, file, outputStream, pgp)) { + if (!decryptToOutputStream(config, file, outputStream, pgp, null)) { return null; } 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(); - decryptToOutputStream(config, file, baos, pgp); - SwingWindow.create("Decrypted file: " + file.getName()) + AtomicReference metaRef = new AtomicReference<>(); + 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) - .text(new String(baos.toByteArray(), StandardCharsets.UTF_8)) + .text(decrypted) + .editable(editable) .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) { @@ -127,7 +155,7 @@ public class EncryptedFileUtil { try { boolean decryptResult; try (FileOutputStream fos = new FileOutputStream(decFile)) { - decryptResult = decryptToOutputStream(config, file, fos, pgp); + decryptResult = decryptToOutputStream(config, file, fos, pgp, null); } if (!decryptResult) { if (decFile.length() == 0) { @@ -164,22 +192,8 @@ public class EncryptedFileUtil { meta.setFileLength(file.length()); meta.setFileLastModified(file.lastModified()); meta.setCompress(compress); - Tlv tlv = TlvUtil.create(1, TinyEncryptMetaUtil.toString(meta)); - try (FileInputStream fis = new FileInputStream(file)) { - try (FileOutputStream fos = new FileOutputStream(encFile)) { - 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, ")); - } - } - } + encryptFromInputStream(fis, encFile, meta); } log.info("Encrypt file success: " + file); 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) { File absFile = file.getAbsoluteFile(); if (absFile.getName().endsWith(TinyEncryptConstant.ENC_FILE_EXT)) {