如何使用Java完成简易密码管理器

来源:Vuejs社区作者:森沢头衔:网络博主
导读:本期聚焦于小伙伴创作的《如何使用Java完成简易密码管理器》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《如何使用Java完成简易密码管理器》有用,将其分享出去将是对创作者最好的鼓励。

使用Java开发简易密码管理器,核心目标是安全存储用户的各类账号密码,避免明文存储带来的泄露风险,同时提供简单的操作入口让用户可以管理自己的密码数据。整个实现过程会围绕加密、存储、交互三个核心模块展开,最终得到一个可以本地运行的命令行版本密码管理工具。

如何使用Java完成简易密码管理器

功能设计与核心依赖

简易密码管理器的核心功能包含四个部分:添加密码记录、查询密码记录、删除密码记录、退出程序。为了实现安全存储,需要使用AES对称加密算法对密码原文进行加密,加密密钥由用户自定义的主管密码生成。整个项目不需要额外引入第三方依赖,使用Java标准库即可完成所有功能。

核心依赖的Java类包含以下几个:

  • javax.crypto.Cipher:用于AES算法的加密解密操作
  • javax.crypto.spec.SecretKeySpec:生成AES加密所需的密钥对象
  • java.io.FileReaderjava.io.FileWriter:用于本地文件的读写操作
  • java.util.Scanner:用于处理用户的命令行输入
  • java.util.ArrayList:用于存储内存中的密码记录列表

AES加密工具类实现

首先封装一个加密工具类,负责将用户的主密码转换为AES密钥,同时提供加密和解密的方法。这里使用AES算法的ECB模式,填充方式为PKCS5Padding,密钥长度固定为128位。

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class AESUtil {
    // 加密算法名称
    private static final String ALGORITHM = "AES";

    // 将用户主密码转换为128位AES密钥
    private static SecretKeySpec getSecretKey(String masterPassword) {
        // 将主密码转为字节数组,截取前16字节作为密钥,不足则补0
        byte[] passwordBytes = masterPassword.getBytes(StandardCharsets.UTF_8);
        byte[] keyBytes = new byte[16];
        for (int i = 0; i < passwordBytes.length && i < 16; i++) {
            keyBytes[i] = passwordBytes[i];
        }
        return new SecretKeySpec(keyBytes, ALGORITHM);
    }

    // 加密方法,传入明文和主密码,返回Base64编码的密文
    public static String encrypt(String plaintext, String masterPassword) throws Exception {
        SecretKeySpec key = getSecretKey(masterPassword);
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] encryptedBytes = cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }

    // 解密方法,传入密文和主密码,返回明文
    public static String decrypt(String ciphertext, String masterPassword) throws Exception {
        SecretKeySpec key = getSecretKey(masterPassword);
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, key);
        byte[] decodedBytes = Base64.getDecoder().decode(ciphertext);
        byte[] decryptedBytes = cipher.doFinal(decodedBytes);
        return new String(decryptedBytes, StandardCharsets.UTF_8);
    }
}

密码记录实体类

定义一个密码记录的实体类,用来存储单条密码的相关信息,包含平台名称、账号、加密后的密码三个属性,同时提供序列化和反序列化的方法,方便将对象转换为字符串存储到文件,或者从文件字符串恢复对象。

public class PasswordRecord {
    // 平台名称,比如微信、淘宝
    private String platform;
    // 对应账号
    private String account;
    // 加密后的密码
    private String encryptedPassword;

    public PasswordRecord(String platform, String account, String encryptedPassword) {
        this.platform = platform;
        this.account = account;
        this.encryptedPassword = encryptedPassword;
    }

    // 将记录转为存储格式的字符串,用|分隔各个字段
    public String toStorageString() {
        return platform + "|" + account + "|" + encryptedPassword;
    }

    // 从存储字符串恢复记录对象
    public static PasswordRecord fromStorageString(String storageStr) {
        String[] parts = storageStr.split("\\|");
        if (parts.length != 3) {
            return null;
        }
        return new PasswordRecord(parts[0], parts[1], parts[2]);
    }

    // getter方法
    public String getPlatform() {
        return platform;
    }

    public String getAccount() {
        return account;
    }

    public String getEncryptedPassword() {
        return encryptedPassword;
    }
}

数据存储管理类

数据存储管理类负责将内存中的密码记录列表持久化到本地文件,以及从本地文件加载数据到内存。这里使用固定的本地文件路径password_data.txt,存储的是每条记录的序列化字符串,每行对应一条记录。

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

public class DataStorageManager {
    // 存储文件的路径
    private static final String FILE_PATH = "password_data.txt";

    // 将密码记录列表保存到文件
    public static void saveRecords(List<PasswordRecord> records) throws IOException {
        try (FileWriter writer = new FileWriter(FILE_PATH, StandardCharsets.UTF_8)) {
            for (PasswordRecord record : records) {
                writer.write(record.toStorageString());
                writer.write("\n");
            }
        }
    }

    // 从文件加载密码记录列表
    public static List<PasswordRecord> loadRecords() throws IOException {
        List<PasswordRecord> records = new ArrayList<>();
        File file = new File(FILE_PATH);
        if (!file.exists()) {
            return records;
        }
        try (BufferedReader reader = new BufferedReader(new FileReader(file, StandardCharsets.UTF_8))) {
            String line;
            while ((line = reader.readLine()) != null) {
                if (!line.trim().isEmpty()) {
                    PasswordRecord record = PasswordRecord.fromStorageString(line);
                    if (record != null) {
                        records.add(record);
                    }
                }
            }
        }
        return records;
    }
}

主程序交互逻辑

主程序负责处理用户的命令行输入,实现菜单展示、功能分发、用户交互的完整流程。用户启动程序后首先要输入主管密码,之后会展示功能菜单,用户选择对应功能后执行对应的操作。

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class PasswordManagerMain {
    private static List<PasswordRecord> records = new ArrayList<>();
    private static String masterPassword = null;
    private static final Scanner scanner = new Scanner(System.in);

    public static void main(String[] args) {
        System.out.println("欢迎使用简易Java密码管理器");
        // 输入主管密码
        System.out.print("请输入主管密码:");
        masterPassword = scanner.nextLine();
        // 加载本地存储的密码记录
        try {
            records = DataStorageManager.loadRecords();
            System.out.println("成功加载" + records.size() + "条密码记录");
        } catch (Exception e) {
            System.out.println("加载本地数据失败,将创建新的数据文件");
        }
        // 展示功能菜单
        while (true) {
            showMenu();
            System.out.print("请输入操作编号:");
            String choice = scanner.nextLine();
            switch (choice) {
                case "1":
                    addPasswordRecord();
                    break;
                case "2":
                    queryPasswordRecord();
                    break;
                case "3":
                    deletePasswordRecord();
                    break;
                case "4":
                    saveAndExit();
                    return;
                default:
                    System.out.println("无效的操作编号,请重新输入");
            }
        }
    }

    // 展示功能菜单
    private static void showMenu() {
        System.out.println("\n====== 密码管理器功能菜单 ======");
        System.out.println("1. 添加密码记录");
        System.out.println("2. 查询密码记录");
        System.out.println("3. 删除密码记录");
        System.out.println("4. 保存并退出");
        System.out.println("==============================");
    }

    // 添加密码记录
    private static void addPasswordRecord() {
        try {
            System.out.print("请输入平台名称:");
            String platform = scanner.nextLine();
            System.out.print("请输入账号:");
            String account = scanner.nextLine();
            System.out.print("请输入密码:");
            String password = scanner.nextLine();
            // 加密密码
            String encryptedPassword = AESUtil.encrypt(password, masterPassword);
            PasswordRecord record = new PasswordRecord(platform, account, encryptedPassword);
            records.add(record);
            System.out.println("密码记录添加成功");
        } catch (Exception e) {
            System.out.println("添加密码记录失败:" + e.getMessage());
        }
    }

    // 查询密码记录
    private static void queryPasswordRecord() {
        if (records.isEmpty()) {
            System.out.println("当前没有存储任何密码记录");
            return;
        }
        System.out.println("\n====== 所有密码记录 ======");
        for (int i = 0; i < records.size(); i++) {
            PasswordRecord record = records.get(i);
            System.out.println("序号:" + (i + 1));
            System.out.println("平台:" + record.getPlatform());
            System.out.println("账号:" + record.getAccount());
            try {
                String decryptedPassword = AESUtil.decrypt(record.getEncryptedPassword(), masterPassword);
                System.out.println("密码:" + decryptedPassword);
            } catch (Exception e) {
                System.out.println("密码解密失败,主管密码可能错误");
            }
            System.out.println("--------------------------");
        }
    }

    // 删除密码记录
    private static void deletePasswordRecord() {
        if (records.isEmpty()) {
            System.out.println("当前没有存储任何密码记录,无法删除");
            return;
        }
        queryPasswordRecord();
        System.out.print("请输入要删除的记录序号:");
        try {
            int index = Integer.parseInt(scanner.nextLine()) - 1;
            if (index >= 0 && index < records.size()) {
                records.remove(index);
                System.out.println("密码记录删除成功");
            } else {
                System.out.println("无效的序号");
            }
        } catch (NumberFormatException e) {
            System.out.println("请输入有效的数字序号");
        }
    }

    // 保存数据并退出
    private static void saveAndExit() {
        try {
            DataStorageManager.saveRecords(records);
            System.out.println("数据保存成功,程序退出");
        } catch (Exception e) {
            System.out.println("数据保存失败:" + e.getMessage());
        }
    }
}

运行与测试说明

将以上四个类的代码放到同一个Java项目下,编译后运行PasswordManagerMain类即可启动程序。首次运行时本地没有数据文件,会提示加载0条记录,用户可以选择添加密码记录,输入对应的平台、账号、密码后,数据会被加密存储到本地文件。之后再次启动程序,输入相同的主管密码就可以查询到之前保存的密码记录。

需要注意主管密码的重要性,一旦主管密码遗忘,所有加密存储的密码都无法解密恢复,因此要妥善保管主管密码。这个简易版本没有做主管密码的校验逻辑,实际使用中可以根据需求增加主管密码二次确认或者密码强度校验的功能。

Java密码管理器AES加密修改时间:2026-06-06 07:16:19

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。