AES加解密工具

背景

当我们想把某些文件上传到云上,方便备份和分享,但是还担心文件泄露,或者不想让提供云存储服务方的管理员看到,可以对文件加密再上传,就可以实现。比如我们的代码不想被审核或者公开,但还想上传到 github 或者 gitee 等开源平台管理。就可以对代码进行加密,再上传。

我习惯将大部分的操作都在终端完成,这样更高效,自由组合程度更高。linux 平台下有 gpg 工具可以对文件加密,但是 win 下没有找到好用的命令行下的加密工具,于是自己用java实现了一个支持批量操作的 aes 加密工具。

特性

命令行操作

例:

加密

java -jar .\AesTool.jar -d ./ -f ".*.java$" -p Aa111111 -en

-d : 指定目录
-f : 加密哪些文件,支持正则表达式
-p : 密码,可以显示输入密码,也可隐式输入,当只有 -p 参数,后面没有密码时,按下回车键后,会提示输入密码,并不会显示到控制台中
-en: 代表要执行加密操作

执行该命令后,会对当前目录下的java文件进行加密,并生成一个 .java.gpg 后缀的加密文件。

解密

java -jar .\AesTool.jar -d ./ -f ".*.gpg$" -p Aa111111 -de

执行该命令后,会对当前目录下的gpg后缀文件解密,覆盖原文件: Main.java.gpg 解密后生成一个 Main.java

关键代码实现

命令行工具

借助 picocli 实现命令行参数的解析,使用起来非常方便,示例:

@CommandLine.Command(name = "Aes 加解密工具", mixinStandardHelpOptions = true, version = "1.0", description = "")
public class Main  implements  Runnable{
    @CommandLine.Option(names = {"-p", "--password"}, description = "密码,小于等于16位", required = true,interactive = true, arity = "0..1", hidden = true)
    private String password;

    @CommandLine.Option(names = {"-en"} , description = "加密", required = false)
    private Boolean en = false;

    @CommandLine.Option(names = {"-de"} , description = "解密", required = false)
    private Boolean de = false;

    @CommandLine.Option(names = {"-d", "--dir"}, description = "目录", required = true)
    private String dir;
    @CommandLine.Option(names = {"-f", "--file"}, description = "文件名,支持正则表达式,例: java -jar .\\AesTool.jar -d ./ -f \".*.java$\" -p Aa111111 -en", required = true)


    @Override
    public void run() {
    }

    public static void main(String[] args) {
        CommandLine.run(new Main(), args);
    }
}

加解密

    public static void aesEn(String key, String filename) throws IOException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        String plaintext = readFile(filename);
        key = String.format("%-16s", key);
        byte[] iv = IV.getBytes(CHARSET);

        // Generate a new AES key
        byte[] keyBytes = key.getBytes(CHARSET);
        SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");

        // Initialize the cipher with the key and IV
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, keySpec, new IvParameterSpec(iv));

        // Encrypt the plaintext
        byte[] ciphertext = cipher.doFinal(plaintext.getBytes(CHARSET));

        // Return the Base64-encoded ciphertext
        plaintext = Base64.getEncoder().encodeToString(ciphertext);
        writeFile(filename + EN_FILE_FLAG, plaintext);
    }

    public static void aesDe(String key, String filename) throws Exception {
        if(!filename.endsWith(EN_FILE_FLAG)){
            System.out.println("不是加密文件,跳过");
            return;
        }
        String encrypted = readFile(filename);
        key = String.format("%-16s", key);
        byte[] iv = IV.getBytes(CHARSET);

        // Generate the AES key from the key bytes
        byte[] keyBytes = key.getBytes(CHARSET);
        SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");

        // Initialize the cipher with the key and IV
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(iv));

        // Decrypt the ciphertext
        byte[] ciphertext = Base64.getDecoder().decode(encrypted);
        byte[] plaintext = cipher.doFinal(ciphertext);

        writeFile(filename.replace(EN_FILE_FLAG,""), new String(plaintext, CHARSET));
    }

完整项目已经开源: https://github.com/dccmmtop/aes_tool

«««< HEAD

=======

259748c5d94d9dc096c2c8ea1a2f98cc9cf7c13a
联系方式: dccmmtop@foxmail.com