我在 Julia 中构建了一个高级密码管理器(哦,是的,Juliaaaa)

发布: (2025年11月30日 GMT+8 14:54)
5 min read
原文: Dev.to

Source: Dev.to

我编写工具是为了避免把无聊的事做两遍,最近我一直在用大家意想不到的语言来实现。这次:Julia。是的,那种大家把它和数学、机器学习联系在一起的科学语言。如果有人不同意,请大声喊出来。

为什么选 Julia 而不是显而易见的 (Python/Go/Rust)?

  • 原生性能:Julia 通过 LLVM 编译成机器码。对于密集的密码学操作(密钥派生、重复哈希),这点很重要。
  • 表达式语法:我可以用看起来像数学的方式编写复杂的数学(比如熵的计算)。
  • 多重分派:我可以根据输入类型定义不同的行为,而不必把代码写成 if/else 的动物园。
  • 交互式 REPL:快速开发、实时测试、随时调整。
  • 惊喜:因为没人会想到,这正合我胃口。

架构:让密码管理器“专业”的因素是什么?

安全需求

  • 真实加密:模拟 AES-256-GCM(演示中使用 XOR + 密钥派生,但结构已经准备好替换为 Nettle.jl
  • 密钥派生:PBKDF2,100,000 次迭代(已为 Argon2 做好准备)
  • 唯一盐值:每条加密记录使用独立的、密码学安全的随机盐
  • 零知识架构:主密码永不存储,只从中派生密钥
  • 安全生成:使用 Julia 的 Random,来源于密码学安全的随机数

功能特性

  • 🎲 可配置选项的密码生成器
  • 📊 熵计算器(本项目的明星)
  • 💾 加密的 JSON 存储
  • 🔍 密码比较器
  • 🎨 直观的 CLI 界面

熵模块:有趣的部分

什么是熵?

在密码学中,熵是 不确定性 的度量。具体来说,它表示你的密码包含多少位不可预测的信息。计算方式如下:

H = L * log2(R)
  • L = 密码长度
  • R = 可能字符集合的大小

直观示例

典型弱密码

Password123!
  • 长度:12 个字符
  • 检测到的字符池:小写字母 (26) + 大写字母 (26) + 数字 (10) + 符号 (32) = 94 个字符
  • 熵:12 × log₂(94) ≈ 78.5 位
  • 估计破解时间:约 95 年(现代 GPU)

真实问题:它是字典单词并遵循可预测模式,字典攻击可以在几分钟内破解。

生成的强密码

xK9#mL2$pQ7@vR4!nF
  • 长度:18 个字符
  • 字符池:94 个字符(全部使用)
  • 熵:18 × log₂(94) ≈ 118 位
  • 估计破解时间:约 1.05 × 10¹⁶ 年(实际上不可行)

在 Julia 中的实现

熵计算

function calculate_entropy(password::String)::Float64
    if isempty(password)
        return 0.0
    end

    # Detectar el pool de caracteres usado
    has_lowercase = any(c -> islowercase(c), password)
    has_uppercase = any(c -> isuppercase(c), password)
    has_digits    = any(c -> isdigit(c), password)
    has_special   = any(c -> !isalnum(c) && !isspace(c), password)

    # Calcular tamaño del pool
    pool_size = 0
    pool_size += has_lowercase ? 26 : 0
    pool_size += has_uppercase ? 26 : 0
    pool_size += has_digits    ? 10 : 0
    pool_size += has_special   ? 32 : 0

    # Fórmula de Shannon
    entropy = length(password) * log2(pool_size)
    return entropy
end

密码生成器

function generate_password(;
    length::Int=16,
    use_lowercase::Bool=true,
    use_uppercase::Bool=true,
    use_digits::Bool=true,
    use_special::Bool=true
)::String
    charset = Char[]
    use_lowercase && append!(charset, LOWERCASE)
    use_uppercase && append!(charset, UPPERCASE)
    use_digits    && append!(charset, DIGITS)
    use_special   && append!(charset, SPECIAL)

    # Generación criptográficamente segura
    password = String([rand(charset) for _ in 1:length])
    return password
end

密钥派生 (PBKDF2)

function derive_key(master_password::String, salt::Vector{UInt8}, iterations::Int=100_000)::Vector{UInt8}
    # Aquí iría la llamada a una implementación de PBKDF2, por ejemplo usando
    # Crypto.jl o Nettle.jl. En el demo se muestra la estructura básica.
    # key = pbkdf2_hmac_sha256(master_password, salt, iterations, 32)
    # return key
end

(管理器的其余代码、加密 JSON 处理、CLI 与测试,已在项目仓库中提供。)

Back to Blog

相关文章

阅读更多 »

理解 ECDSA

本文基本上是一个从零开始理解 ECDSA(Elliptic Curve Digital Signature Algorithm)的练习。我只假设一些基础数学和一个意愿……