说到文本加密,很多人会把 AES、Base64、MD5 混为一谈。实际上这三种东西性质完全不一样——一种是真加密,一种是编码,还有一种是单向哈希。用错场景不仅达不到目的,还可能给你一种虚假的安全感。下面把它们的区别、适用场景和注意事项说清楚。

AES:可逆的对称加密

AES(Advanced Encryption Standard)是目前用的最多的对称加密算法。对称的意思是加密和解密用的是同一个密钥。你用密钥 A 把明文加密成密文,拿到密文之后还得用同一个密钥 A 才能还原出原文。

AES 有几种密钥长度可选:128 位、192 位和 256 位。密钥越长,暴力破解需要的时间就越长,当然计算开销也稍微大一点。目前 AES-256 在绝大多数场景下够用了。

实际使用的时候还会涉及到加密模式(比如 CBC、GCM)和填充方式(PKCS7)。这些参数选不对也会出问题。GCM 模式除了加密还能同时做完整性校验,比较推荐。

AES 适合的场景:

  • 保护传输中的敏感数据(配合 HTTPS 使用或作为额外一层加密)
  • 本地存储敏感信息(比如把配置文件里的密码加密后存磁盘)
  • 客户端和服务端之间约定好密钥后的数据交换

AES 不适合的场景:需要公开分享数据给陌生人解密的场合(对方得有你的密钥才行,分发密钥本身就是个问题)。这种情况下应该用非对称加密(RSA 之类)。

Base64:不是加密,是编码

这个要强调一下:Base64 根本不是加密。它是一种编码方式,作用是把二进制数据转换成只包含 ASCII 可打印字符的文本格式。

原理很简单:把原始数据每 6 个 bit 分一组,映射到一个字符表(A-Z、a-z、0-9、+、/,共 64 个字符,所以叫 Base64)。编码之后的数据体积会比原来大大约 33%。

任何人拿到 Base64 编码后的字符串都能用标准算法解码回原文,不存在"解不开"的问题。它没有密钥的概念。

那为什么到处都在用它?因为有些系统或协议只能处理纯文本。比如:

  • Email 附件(MIME 协议要求二进制数据转成 ASCII 传输)
  • JSON 里嵌套图片或二进制数据
  • Cookie 或 URL 里携带少量二进制信息
  • XML/SOAP 这种纯文本协议里传非文本内容

如果你看到有人用 Base64 存密码然后号称"加密了",那基本等于明文存。别这么干。

MD5 和 SHA:单向哈希函数

哈希(Hash)跟前面两种又不一样。哈希函数的特点是单向不可逆:你能从任意输入算出一个固定长度的哈希值,但没法从这个值反推出原来的内容。

MD5 输出 128 位(32 个十六进制字符),SHA-1 输出 160 位,SHA-256 输出 256 位。理想情况下,输入内容只要改一个字母,输出的哈希值就会完全不同(雪崩效应)。

常见的用途:

  • 校验文件完整性:下载软件之后跑一遍 SHA-256 跟官网公布的值对比,确认文件没被篡改
  • 密码存储:数据库里不存明文密码,存的是密码的哈希值(当然还要加盐,下面会讲)
  • 数字签名:先对消息算哈希,再用私钥对哈希值签名

关于 MD5 要多说一句:MD5 已经被证明存在碰撞攻击,安全性不够用了。现在新项目别用 MD5,至少用 SHA-256。SHA-1 也不太安全,尽量上 SHA-2 系列(256 或更高)。

为什么说密钥管理比算法更重要

不管你用的是 AES 还是别的什么对称加密,安全性的关键在密钥而不是算法本身。AES-256 算法本身很硬,但如果你的密钥是 123456 或者 password,那破解成本约等于零。

几个基本原则:

  • 密钥要有足够的随机性和长度(至少 16 字节的随机数)
  • 不要把密钥写进代码里提交到 Git 仓库
  • 定期轮换密钥,尤其是怀疑泄露的时候
  • 生产环境用专门的密钥管理服务(KMS)或环境变量注入

对于密码存储的场景,光哈希还不够。两个用户如果用相同密码,哈希结果一样,攻击者一看就知道密码重复了。解决办法是加盐(salt):每个用户生成一个随机字符串拼在密码后面再算哈希。这样即使密码相同,哈希结果也不一样。更进一步的方案是用 bcrypt、scrypt 或 PBKDF2 这些专门为密码存储设计的慢哈希算法,增加暴力破解的成本。

什么时候不该自己实现

如果你在做正式产品涉及加密功能,有几个坑要注意:

  • 别自己写加密算法:AES 的实现细节很多(字节序、填充、模式、IV 处理),手写很容易出错。用成熟库(OpenSSL、libsodium、Web Crypto API)
  • 别自己设计协议:如果需要通信加密,直接用 TLS/SSL。在 TLS 之上再加一层自定义加密通常没必要还容易引入漏洞
  • 注意时序攻击:某些不当实现的字符串比较操作会因为耗时差异泄露信息。库函数通常已经处理好了这个问题
  • 随机数要用密码学安全的源:Math.random() 这类伪随机数生成器不适合用来生成密钥或 IV

在线加密工具适合什么场景

这个在线文本加密/编码工具适合以下场景:

  • 学习和理解各种算法的区别:亲手试一遍比看文档印象深
  • 快速测试:验证某个字符串 Base64 编码之后长什么样,或者一段文字用指定密钥 AES 加密的结果
  • 临时处理非敏感数据:比如开发调试阶段需要对一些配置信息做编解码

不适合的场景:处理真实的敏感数据(密码、密钥、个人信息等)并期望得到生产级别的安全保障。浏览器端的 JavaScript 加密无法保证密钥不泄露,页面代码也随时可能被修改。这类需求请用专业的命令行工具或经过审计的库。

常见问题

AES 加密后数据变长了多少?

AES 加密后数据长度会按 16 字节块对齐,通常比原文长 1-16 字节。再加上 Base64 编码(为了文本传输),最终长度大约是原文的 1.3-1.5 倍。具体取决于加密模式和填充方式。

MD5 还安全吗?

不推荐用于安全场景。MD5 存在已知的碰撞漏洞,攻击者可以构造两个不同内容产生相同 MD5 值的文件。但对于文件完整性校验、缓存 key 生成等非安全用途,MD5 仍然够用。密码存储建议用 bcrypt 或 Argon2。

Base64 算加密吗?

不算。Base64 是编码方式,不是加密。任何人都能把 Base64 解码回原文,不需要密钥。它的作用是把二进制数据转成文本格式方便传输,不要用它来保护敏感数据。看到有人把 Base64 当加密用,那就是搞错了。