feat: v0.4.0, decrypt and edit tinyenc
This commit is contained in:
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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");
|
||||||
|
|||||||
@@ -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";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user