diff --git a/src/main/java/me/hatter/tools/tinyencrypt/TinyEncryptMain.java b/src/main/java/me/hatter/tools/tinyencrypt/TinyEncryptMain.java index 1bb5e4e..ff5ecb0 100644 --- a/src/main/java/me/hatter/tools/tinyencrypt/TinyEncryptMain.java +++ b/src/main/java/me/hatter/tools/tinyencrypt/TinyEncryptMain.java @@ -1,7 +1,5 @@ package me.hatter.tools.tinyencrypt; -import com.alibaba.fastjson.JSON; -import me.hatter.tools.commons.bytes.ByteUtil; import me.hatter.tools.commons.bytes.Bytes; import me.hatter.tools.commons.exception.JumpOutException; import me.hatter.tools.commons.io.RFile; @@ -9,27 +7,13 @@ 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.bc.BCUtil; -import me.hatter.tools.commons.security.crypt.AESCryptTool; import me.hatter.tools.commons.security.digest.Digests; -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.random.RandomTool; -import me.hatter.tools.commons.string.JSONUtil; import me.hatter.tools.commons.string.StringUtil; -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.config.TinyEncryptConstant; import me.hatter.tools.tinyencrypt.encrypt.EncryptedFileUtil; -import me.hatter.tools.tinyencrypt.encrypt.TinyEncryptMeta; -import me.hatter.tools.tinyencrypt.util.CardCliUtil; import java.io.File; -import java.io.FileInputStream; -import java.security.KeyPair; -import java.util.Date; -import java.util.Optional; public class TinyEncryptMain { private static final LogTool log; @@ -39,114 +23,6 @@ public class TinyEncryptMain { log = LogTools.getLogTool(TinyEncryptMain.class); } - private static void doEncryptConfigLocalPrivateKey(TinyEncryptArgs tinyEncryptArgs) { - TinyEncryptConfig config = TinyEncryptMainUtil.loadTinyEncryptConfig(tinyEncryptArgs); - if (config == null) { - return; - } - if (StringUtil.isEmpty(config.getLocalPrivateKeyPem())) { - log.error("Local private key pem is empty!"); - return; - } - if (StringUtil.isNotEmpty(config.getLocalPrivateKeyPemEncrypted()) - || StringUtil.isNotEmpty(config.getLocalPrivateKeyPemChallenge())) { - log.error("Local private key is already encrypted!"); - return; - } - String challenge = RandomTool.secureRandom().nextBytes(16).asHex(); - Optional keyOpt = CardCliUtil.getChall(config.getCardCli(), challenge); - if (!keyOpt.isPresent()) { - return; - } - byte[] key = keyOpt.get(); - String localPrivateKeyPemEncrypted = AESCryptTool.gcmEncrypt(key).from(Bytes.from(config.getLocalPrivateKeyPem())).toBytes().asBase64(); - - RFile tinyEncryptConfigRFile = TinyEncryptArgsUtil.getTinyEncryptConfigRFile(tinyEncryptArgs); - config.setLocalPrivateKeyPem(null); - config.setLocalPrivateKeyPemChallenge(challenge); - config.setLocalPrivateKeyPemEncrypted(localPrivateKeyPemEncrypted); - tinyEncryptConfigRFile.write(JSONUtil.pretty(config)); - log.info("Write file success: " + tinyEncryptConfigRFile.file()); - } - - private static void doInitConfig(TinyEncryptArgs tinyEncryptArgs) { - if (StringUtil.isEmpty(tinyEncryptArgs.key)) { - log.error("Default key is not assigned"); - return; - } - RFile writeTinyEncryptConfigRFile = TinyEncryptArgsUtil.getTinyEncryptConfigRFile(tinyEncryptArgs); - 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()); - } - - private static void fileInfo(TinyEncryptArgs tinyEncryptArgs) { - if ((tinyEncryptArgs.files == null) || (tinyEncryptArgs.files.length == 0)) { - log.error("No file assigned"); - return; - } - for (File f : tinyEncryptArgs.files) { - boolean isTinyEncFile = f.getName().endsWith(TinyEncryptConstant.ENC_FILE_EXT); - if (!isTinyEncFile) { - log.warn("File is not tiny enc file: " + f); - } else { - try { - try (FileInputStream fis = new FileInputStream(f)) { - Tlv tlv = TlvUtil.readTlv(fis); - TinyEncryptMeta meta = tlv.getValueAsBytes().asJSONObject(TinyEncryptMeta.class); - StringBuilder sb = new StringBuilder(256); - sb.append("File: ").append(f); - if ((meta.getCompress() != null) && meta.getCompress()) { - sb.append(" [compressed]"); - } - sb.append("\n"); - sb.append("File version: ").append(meta.getVersion()).append("\n"); - if (meta.getFileLength() != null) { - sb.append("File size: ").append(meta.getFileLength()) - .append(" (") - .append(ByteUtil.formatBytes(meta.getFileLength())) - .append(")\n"); - } - if (meta.getFileLastModified() != null) { - sb.append("Last modified: ") - .append(new Date(meta.getFileLastModified())) - .append("\n"); - } - sb.append("Enc file created: ") - .append(new Date(meta.getCreated())) - .append("\n"); - if (StringUtil.isNotBlank(meta.getPgpEnvelop())) { - sb.append("PGP envelop: YES\n"); - } else { - sb.append("PGP envelop: NO\n"); - } - if (StringUtil.isNotBlank(meta.getPgpFingerprint())) { - sb.append("PGP fingerprint: ") - .append(meta.getPgpFingerprint()) - .append("\n"); - } - sb.append("Agent: ").append(meta.getUserAgent()); - if (StringUtil.isNotBlank(meta.getComment())) { - sb.append("Comment: ").append(meta.getComment()).append("\n"); - } - - log.info(sb.toString()); - } - } catch (Exception e) { - log.warn("Read tiny encrypt file failed: " + e.getMessage() + ", file: " + f); - } - } - } - } - public static void main(String[] args) { TinyEncryptArgs tinyEncryptArgs = TinyEncryptArgsUtil.parseTinyEncryptArgs(args); if (tinyEncryptArgs == null) { @@ -155,15 +31,15 @@ public class TinyEncryptMain { BCUtil.useBc(!tinyEncryptArgs.useJce); // ==================================================================================== if (tinyEncryptArgs.doInitConfig) { // --init-config - doInitConfig(tinyEncryptArgs); + TinyEncryptMainUtil.initConfig(tinyEncryptArgs); return; } if (tinyEncryptArgs.doEncryptConfigLocalPrivateKey) { // --encrypt-config-local-private-key - doEncryptConfigLocalPrivateKey(tinyEncryptArgs); + TinyEncryptMainUtil.encryptConfigLocalPrivateKey(tinyEncryptArgs); return; } if (tinyEncryptArgs.fileInfo) { // --info - fileInfo(tinyEncryptArgs); + TinyEncryptMainUtil.fileInfo(tinyEncryptArgs); return; } // ==================================================================================== @@ -183,13 +59,11 @@ public class TinyEncryptMain { if (config == null) { return; } - 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) { diff --git a/src/main/java/me/hatter/tools/tinyencrypt/TinyEncryptMainUtil.java b/src/main/java/me/hatter/tools/tinyencrypt/TinyEncryptMainUtil.java index 90819e9..735eb20 100644 --- a/src/main/java/me/hatter/tools/tinyencrypt/TinyEncryptMainUtil.java +++ b/src/main/java/me/hatter/tools/tinyencrypt/TinyEncryptMainUtil.java @@ -1,14 +1,142 @@ package me.hatter.tools.tinyencrypt; +import com.alibaba.fastjson.JSON; +import me.hatter.tools.commons.bytes.ByteUtil; +import me.hatter.tools.commons.bytes.Bytes; import me.hatter.tools.commons.io.RFile; import me.hatter.tools.commons.log.LogTool; import me.hatter.tools.commons.log.LogTools; +import me.hatter.tools.commons.security.crypt.AESCryptTool; +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.random.RandomTool; +import me.hatter.tools.commons.string.JSONUtil; import me.hatter.tools.commons.string.StringUtil; +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.config.TinyEncryptConstant; +import me.hatter.tools.tinyencrypt.encrypt.TinyEncryptMeta; +import me.hatter.tools.tinyencrypt.util.CardCliUtil; + +import java.io.File; +import java.io.FileInputStream; +import java.security.KeyPair; +import java.util.Date; +import java.util.Optional; public class TinyEncryptMainUtil { private static final LogTool log = LogTools.getLogTool(TinyEncryptMainUtil.class); + public static void encryptConfigLocalPrivateKey(TinyEncryptArgs tinyEncryptArgs) { + TinyEncryptConfig config = loadTinyEncryptConfig(tinyEncryptArgs); + if (config == null) { + return; + } + if (StringUtil.isEmpty(config.getLocalPrivateKeyPem())) { + log.error("Local private key pem is empty!"); + return; + } + if (StringUtil.isNotEmpty(config.getLocalPrivateKeyPemEncrypted()) + || StringUtil.isNotEmpty(config.getLocalPrivateKeyPemChallenge())) { + log.error("Local private key is already encrypted!"); + return; + } + String challenge = RandomTool.secureRandom().nextBytes(16).asHex(); + Optional keyOpt = CardCliUtil.getChall(config.getCardCli(), challenge); + if (!keyOpt.isPresent()) { + return; + } + byte[] key = keyOpt.get(); + String localPrivateKeyPemEncrypted = AESCryptTool.gcmEncrypt(key).from(Bytes.from(config.getLocalPrivateKeyPem())).toBytes().asBase64(); + + RFile tinyEncryptConfigRFile = TinyEncryptArgsUtil.getTinyEncryptConfigRFile(tinyEncryptArgs); + config.setLocalPrivateKeyPem(null); + config.setLocalPrivateKeyPemChallenge(challenge); + config.setLocalPrivateKeyPemEncrypted(localPrivateKeyPemEncrypted); + tinyEncryptConfigRFile.write(JSONUtil.pretty(config)); + log.info("Write file success: " + tinyEncryptConfigRFile.file()); + } + + public static void initConfig(TinyEncryptArgs tinyEncryptArgs) { + if (StringUtil.isEmpty(tinyEncryptArgs.key)) { + log.error("Default key is not assigned"); + return; + } + RFile writeTinyEncryptConfigRFile = TinyEncryptArgsUtil.getTinyEncryptConfigRFile(tinyEncryptArgs); + 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()); + } + + public static void fileInfo(TinyEncryptArgs tinyEncryptArgs) { + if ((tinyEncryptArgs.files == null) || (tinyEncryptArgs.files.length == 0)) { + log.error("No file assigned"); + return; + } + for (File f : tinyEncryptArgs.files) { + boolean isTinyEncFile = f.getName().endsWith(TinyEncryptConstant.ENC_FILE_EXT); + if (!isTinyEncFile) { + log.warn("File is not tiny enc file: " + f); + } else { + try { + try (FileInputStream fis = new FileInputStream(f)) { + Tlv tlv = TlvUtil.readTlv(fis); + TinyEncryptMeta meta = tlv.getValueAsBytes().asJSONObject(TinyEncryptMeta.class); + StringBuilder sb = new StringBuilder(256); + sb.append("File: ").append(f); + if ((meta.getCompress() != null) && meta.getCompress()) { + sb.append(" [compressed]"); + } + sb.append("\n"); + sb.append("File version: ").append(meta.getVersion()).append("\n"); + if (meta.getFileLength() != null) { + sb.append("File size: ").append(meta.getFileLength()) + .append(" (") + .append(ByteUtil.formatBytes(meta.getFileLength())) + .append(")\n"); + } + if (meta.getFileLastModified() != null) { + sb.append("Last modified: ") + .append(new Date(meta.getFileLastModified())) + .append("\n"); + } + sb.append("Enc file created: ") + .append(new Date(meta.getCreated())) + .append("\n"); + if (StringUtil.isNotBlank(meta.getPgpEnvelop())) { + sb.append("PGP envelop: YES\n"); + } else { + sb.append("PGP envelop: NO\n"); + } + if (StringUtil.isNotBlank(meta.getPgpFingerprint())) { + sb.append("PGP fingerprint: ") + .append(meta.getPgpFingerprint()) + .append("\n"); + } + sb.append("Agent: ").append(meta.getUserAgent()); + if (StringUtil.isNotBlank(meta.getComment())) { + sb.append("Comment: ").append(meta.getComment()).append("\n"); + } + + log.info(sb.toString()); + } + } catch (Exception e) { + log.warn("Read tiny encrypt file failed: " + e.getMessage() + ", file: " + f); + } + } + } + } + public static TinyEncryptConfig loadTinyEncryptConfig(TinyEncryptArgs tinyEncryptArgs) { RFile tinyEncryptConfigRFile = TinyEncryptArgsUtil.getTinyEncryptConfigRFile(tinyEncryptArgs); if (tinyEncryptConfigRFile.notExists()) {