From 8d656b518e0b073d6a31ea98f22ff102d021fa19 Mon Sep 17 00:00:00 2001 From: Hatter Jiang Date: Fri, 16 Apr 2021 01:03:59 +0800 Subject: [PATCH] feat add init config --- build.json | 2 +- .../tools/tinyencrypt/TinyEncryptArgs.java | 8 ++- .../tools/tinyencrypt/TinyEncryptMain.java | 56 ++++++++++++++++++- .../tinyencrypt/config/TinyEncryptConfig.java | 18 ++++++ .../encrypt/EncryptedFileUtil.java | 5 +- .../tinyencrypt/encrypt/TinyEncryptMeta.java | 15 +++++ .../encrypt/TinyEncryptMetaUtil.java | 23 +++++++- 7 files changed, 121 insertions(+), 6 deletions(-) diff --git a/build.json b/build.json index 2e6629d..0012857 100644 --- a/build.json +++ b/build.json @@ -12,7 +12,7 @@ }, "repo": { "dependencies": [ - "me.hatter:commons:3.31", + "me.hatter:commons:3.33", "org.bouncycastle:bcprov-jdk15on:1.62", "info.picocli:picocli:4.6.1" ], diff --git a/src/main/java/me/hatter/tools/tinyencrypt/TinyEncryptArgs.java b/src/main/java/me/hatter/tools/tinyencrypt/TinyEncryptArgs.java index 74902f2..52270dd 100644 --- a/src/main/java/me/hatter/tools/tinyencrypt/TinyEncryptArgs.java +++ b/src/main/java/me/hatter/tools/tinyencrypt/TinyEncryptArgs.java @@ -7,7 +7,7 @@ import java.io.File; @CommandLine.Command(name = "tiny-encrypt", version = "tiny-encrypt v0.1.0") public class TinyEncryptArgs { @CommandLine.Option(names = {"-e", "--encrypt"}, description = "Encrypt file") - boolean encrypt = false; + boolean encrypt = false; @CommandLine.Option(names = {"-d", "--decrypt"}, description = "Decrypt file") boolean decrypt = false; @@ -18,9 +18,15 @@ public class TinyEncryptArgs { @CommandLine.Option(names = {"-c", "--comment"}, description = "Encrypt comment") String comment; + @CommandLine.Option(names = {"--config"}, description = "Encrypt config") + File config; + @CommandLine.Parameters(paramLabel = "FILE", description = "Encrypt or Decrypt files") File[] files; + @CommandLine.Option(names = {"--init-config"}, description = "Init encrypt config") + boolean doInitConfig = false; + @CommandLine.Option(names = {"-h", "--help"}, usageHelp = true, description = "Display a help message") boolean helpRequested = false; diff --git a/src/main/java/me/hatter/tools/tinyencrypt/TinyEncryptMain.java b/src/main/java/me/hatter/tools/tinyencrypt/TinyEncryptMain.java index cee8ce3..72c82c9 100644 --- a/src/main/java/me/hatter/tools/tinyencrypt/TinyEncryptMain.java +++ b/src/main/java/me/hatter/tools/tinyencrypt/TinyEncryptMain.java @@ -1,16 +1,26 @@ package me.hatter.tools.tinyencrypt; +import com.alibaba.fastjson.JSON; import me.hatter.tools.commons.exception.JumpOutException; +import me.hatter.tools.commons.io.RFile; import me.hatter.tools.commons.log.LogConfig; import me.hatter.tools.commons.log.LogTool; import me.hatter.tools.commons.log.LogTools; +import me.hatter.tools.commons.security.key.KeyPairTool; +import me.hatter.tools.commons.security.key.KeyUtil; +import me.hatter.tools.commons.security.key.PKType; +import me.hatter.tools.commons.string.StringUtil; +import me.hatter.tools.tinyencrypt.config.TinyEncryptConfig; import me.hatter.tools.tinyencrypt.encrypt.EncryptedFileUtil; +import me.hatter.tools.tinyencrypt.encrypt.TinyEncryptMetaUtil; import me.hatter.tools.tinyencrypt.util.BCUtil; import picocli.CommandLine; import java.io.File; +import java.security.KeyPair; public class TinyEncryptMain { + private static final String DEFAULT_TINY_ENCRYPT_CONFIG = "~/.tinyencrypt_config.json"; private static final LogTool log; static { @@ -32,6 +42,33 @@ public class TinyEncryptMain { return; } + // ==================================================================================== + if (tinyEncryptArgs.doInitConfig) { + if (StringUtil.isEmpty(tinyEncryptArgs.key)) { + log.error("Default key is not assigned"); + return; + } + RFile writeTinyEncryptConfigRFile; + if (tinyEncryptArgs.config != null) { + writeTinyEncryptConfigRFile = RFile.from(tinyEncryptArgs.config); + } else { + writeTinyEncryptConfigRFile = RFile.from(DEFAULT_TINY_ENCRYPT_CONFIG); + } + if (writeTinyEncryptConfigRFile.exists()) { + log.error("File exists: " + tinyEncryptArgs.config); + return; + } + KeyPair keyPair = KeyPairTool.ins(PKType.secp256r1).generate().getKeyPair(); + TinyEncryptConfig writeTinyEncryptConfig = new TinyEncryptConfig(); + writeTinyEncryptConfig.setDefaultKeyName(tinyEncryptArgs.key); + writeTinyEncryptConfig.setLocalPublicKeyPem(KeyUtil.serializePublicKeyToPEM(keyPair.getPublic())); + writeTinyEncryptConfig.setLocalPrivateKeyPem(KeyUtil.serializePrivateKeyToPEM(keyPair.getPrivate())); + writeTinyEncryptConfigRFile.write(JSON.toJSONString(writeTinyEncryptConfig, true)); + log.info("Write file success: " + writeTinyEncryptConfigRFile.file()); + return; + } + // ==================================================================================== + boolean isEncrypt = tinyEncryptArgs.encrypt; boolean isDecrypt = tinyEncryptArgs.decrypt; if (isEncrypt && isDecrypt) { @@ -43,17 +80,34 @@ public class TinyEncryptMain { return; } + TinyEncryptConfig config; + if (tinyEncryptArgs.config != null) { + config = RFile.from(tinyEncryptArgs.config).parseJSONObject(TinyEncryptConfig.class); + } else { + RFile defaultTinyEncryptConfigFile = RFile.from(DEFAULT_TINY_ENCRYPT_CONFIG); + if (defaultTinyEncryptConfigFile.notExists()) { + log.error("Config file not assigned, and no default config file: " + DEFAULT_TINY_ENCRYPT_CONFIG); + return; + } + config = defaultTinyEncryptConfigFile.parseJSONObject(TinyEncryptConfig.class); + } + if (StringUtil.isNotBlank(tinyEncryptArgs.key)) { + log.info("Using key from args: " + tinyEncryptArgs.key); + config.setDefaultKeyName(tinyEncryptArgs.key); + } + if ((tinyEncryptArgs.files == null) || (tinyEncryptArgs.files.length == 0)) { log.error("FILE is not assigned."); return; } int total = tinyEncryptArgs.files.length; + try { int index = 1; for (File f : tinyEncryptArgs.files) { log.info("Start processing file: " + f + ", " + index + " of " + total); if (tinyEncryptArgs.encrypt) { - EncryptedFileUtil.encryptFile(tinyEncryptArgs.key, f, tinyEncryptArgs.comment); + EncryptedFileUtil.encryptFile(config, tinyEncryptArgs.key, f, tinyEncryptArgs.comment); } else { EncryptedFileUtil.decryptFile(f); } diff --git a/src/main/java/me/hatter/tools/tinyencrypt/config/TinyEncryptConfig.java b/src/main/java/me/hatter/tools/tinyencrypt/config/TinyEncryptConfig.java index 6391ccd..a71bd75 100644 --- a/src/main/java/me/hatter/tools/tinyencrypt/config/TinyEncryptConfig.java +++ b/src/main/java/me/hatter/tools/tinyencrypt/config/TinyEncryptConfig.java @@ -2,6 +2,8 @@ package me.hatter.tools.tinyencrypt.config; public class TinyEncryptConfig { private String defaultKeyName; + private String localPublicKeyPem; + private String localPrivateKeyPem; public String getDefaultKeyName() { return defaultKeyName; @@ -10,4 +12,20 @@ public class TinyEncryptConfig { public void setDefaultKeyName(String defaultKeyName) { this.defaultKeyName = defaultKeyName; } + + public String getLocalPublicKeyPem() { + return localPublicKeyPem; + } + + public void setLocalPublicKeyPem(String localPublicKeyPem) { + this.localPublicKeyPem = localPublicKeyPem; + } + + public String getLocalPrivateKeyPem() { + return localPrivateKeyPem; + } + + public void setLocalPrivateKeyPem(String localPrivateKeyPem) { + this.localPrivateKeyPem = localPrivateKeyPem; + } } 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 cb4e7c2..536d160 100644 --- a/src/main/java/me/hatter/tools/tinyencrypt/encrypt/EncryptedFileUtil.java +++ b/src/main/java/me/hatter/tools/tinyencrypt/encrypt/EncryptedFileUtil.java @@ -9,6 +9,7 @@ import me.hatter.tools.commons.log.LogTools; import me.hatter.tools.commons.security.crypt.CryptOutputStream; import me.hatter.tools.commons.tlv.Tlv; import me.hatter.tools.commons.tlv.TlvUtil; +import me.hatter.tools.tinyencrypt.config.TinyEncryptConfig; import me.hatter.tools.tinyencrypt.util.BCUtil; import java.io.*; @@ -52,7 +53,7 @@ public class EncryptedFileUtil { } } - public static void encryptFile(String keyName, File file, String comment) { + public static void encryptFile(TinyEncryptConfig config, String keyName, File file, String comment) { File encFile = getEncryptFile(file); if (encFile.exists()) { log.warn("File exists, skip: " + encFile); @@ -61,7 +62,7 @@ public class EncryptedFileUtil { try { try (FileInputStream fis = new FileInputStream(file)) { try (FileOutputStream fos = new FileOutputStream(encFile)) { - TinyEncryptMeta meta = TinyEncryptMetaUtil.create(keyName, comment); + TinyEncryptMeta meta = TinyEncryptMetaUtil.create(config, comment); TlvUtil.writeTlv(fos, TlvUtil.create(1, TinyEncryptMetaUtil.toString(meta))); fos.flush(); try (OutputStream newOs = getEncryptOutputStream(fos, meta)) { diff --git a/src/main/java/me/hatter/tools/tinyencrypt/encrypt/TinyEncryptMeta.java b/src/main/java/me/hatter/tools/tinyencrypt/encrypt/TinyEncryptMeta.java index 4d4581e..fa6c028 100644 --- a/src/main/java/me/hatter/tools/tinyencrypt/encrypt/TinyEncryptMeta.java +++ b/src/main/java/me/hatter/tools/tinyencrypt/encrypt/TinyEncryptMeta.java @@ -2,6 +2,8 @@ package me.hatter.tools.tinyencrypt.encrypt; import com.alibaba.fastjson.annotation.JSONField; +import java.util.Arrays; + public class TinyEncryptMeta { private String version; private long created; @@ -67,4 +69,17 @@ public class TinyEncryptMeta { public void setNonce(byte[] nonce) { this.nonce = nonce; } + + @Override + public String toString() { + return "TinyEncryptMeta{" + + "version='" + version + '\'' + + ", created=" + created + + ", userAgent='" + userAgent + '\'' + + ", comment='" + comment + '\'' + + ", envelop='" + envelop + '\'' + + ", dataKey=***" + + ", nonce=***" + + '}'; + } } diff --git a/src/main/java/me/hatter/tools/tinyencrypt/encrypt/TinyEncryptMetaUtil.java b/src/main/java/me/hatter/tools/tinyencrypt/encrypt/TinyEncryptMetaUtil.java index 0c6972a..6ef610a 100644 --- a/src/main/java/me/hatter/tools/tinyencrypt/encrypt/TinyEncryptMetaUtil.java +++ b/src/main/java/me/hatter/tools/tinyencrypt/encrypt/TinyEncryptMetaUtil.java @@ -8,9 +8,19 @@ import me.hatter.tools.commons.log.LogTool; import me.hatter.tools.commons.log.LogTools; import me.hatter.tools.commons.network.HttpRequest; import me.hatter.tools.commons.os.OSUtil; +import me.hatter.tools.commons.security.key.KeyPairTool; +import me.hatter.tools.commons.security.key.KeyUtil; +import me.hatter.tools.commons.security.key.PKType; +import me.hatter.tools.commons.security.pem.PEMUtil; import me.hatter.tools.commons.security.random.RandomTool; +import me.hatter.tools.commons.security.rsa.PrivateKeyParseTool; +import me.hatter.tools.commons.security.sign.Signatures; +import me.hatter.tools.tinyencrypt.config.TinyEncryptConfig; import me.hatter.tools.tinyencrypt.config.TinyEncryptConstant; +import java.security.KeyPair; +import java.security.PrivateKey; +import java.security.PublicKey; import java.util.ArrayList; import java.util.Base64; import java.util.List; @@ -27,9 +37,20 @@ public class TinyEncryptMetaUtil { return JSON.parseObject(meta, TinyEncryptMeta.class); } - public static TinyEncryptMeta create(String name, String comment) { + public static TinyEncryptMeta create(TinyEncryptConfig config, String comment) { + PublicKey publicKey = KeyUtil.parsePublicKeyPEM(config.getLocalPublicKeyPem()); + PrivateKey privateKey = KeyUtil.parsePrivateKeyPEM(config.getLocalPrivateKeyPem()); + String name = config.getDefaultKeyName(); + + String timestamp = String.valueOf(System.currentTimeMillis()); + String toBeSigned = name + "|" + timestamp; + Bytes sign = Signatures.sha256(privateKey).sign(toBeSigned); + List keyValues = new ArrayList<>(); keyValues.add(new HttpRequest.KeyValue("name", name)); + keyValues.add(new HttpRequest.KeyValue("timestamp", timestamp)); + keyValues.add(new HttpRequest.KeyValue("dataKeyPublicKey", KeyUtil.serializePublicKeyToPEM(publicKey))); + keyValues.add(new HttpRequest.KeyValue("dataKeyRequestSign", sign.asBase64())); log.info("Get data key from kms, key name: " + name); Bytes response = HttpRequest.fromUrl(KMS_GET_DATA_KEY).post(keyValues); JSONObject responseObject = response.asJSON();