加密基础与算法:对称加密、非对称加密、哈希与密钥管理

各位好,咱们直接进入正题。加密这东西,说白了就是给数据加把锁。你想想看,存储系统里存着用户密码、交易记录、企业机密——要是明文裸奔,那跟把保险柜门敞开有什么区别?

我刚开始做存储那会儿,觉得加密就是调个库、传个参数的事。直到有一次做安全审计,发现密钥硬编码在配置文件里……嗯,从那以后我再也不敢小看加密了。今天咱们把四种核心武器讲透:AES、RSA、SHA-256、密钥管理。

核心原则:加密不是为了防住所有攻击者,而是让攻击成本远高于数据价值。你不需要造轮子,但必须知道轮子怎么转。

加密基础与算法知识体系 加密基础 对称加密 (AES) 非对称加密 (RSA) 哈希算法 (SHA-256) 密钥管理 AES-128/256 RSA-2048/4096 SHA-2 家族 HSM / KMS 核心关系 对称加密快 → 加密数据 非对称加密慢 → 加密对称密钥 哈希算法 → 完整性校验 + 密码存储

对称加密:AES 算法

对称加密,就是加密和解密用同一把钥匙。你想想看,就像你家大门——钥匙既能锁门也能开门。AES 是目前最主流的对称加密标准,没有之一。

我个人习惯用 AES-256-GCM 模式。为什么?因为 GCM 模式自带认证标签,能同时保证机密性和完整性。我在项目中遇到过有人用 AES-ECB 模式加密数据库字段——结果相同明文产生相同密文,攻击者一看就知道哪些记录重复。这简直是给黑客送情报。

AES 模式 特点 推荐场景
ECB 简单,但相同明文→相同密文 不要用
CBC 需要 IV,可并行解密 文件加密(旧系统兼容)
GCM 认证加密,抗篡改 首选:网络传输、存储加密
CTR 可并行,无填充 高性能场景

我的建议:新项目一律用 AES-256-GCM。密钥长度选 256 位,IV 用 12 字节随机数。别自己拼凑加密方案——GCM 已经帮你处理了认证问题。

// Go 语言示例:AES-256-GCM 加密
import (
    "crypto/aes"
    "crypto/cipher"
    "crypto/rand"
)

func encrypt(plaintext []byte, key []byte) ([]byte, error) {
    block, err := aes.NewCipher(key)
    if err != nil {
        return nil, err
    }
    gcm, err := cipher.NewGCM(block)
    if err != nil {
        return nil, err
    }
    nonce := make([]byte, gcm.NonceSize())
    if _, err := rand.Read(nonce); err != nil {
        return nil, err
    }
    // 密文 = nonce + 加密数据 + 认证标签
    return gcm.Seal(nonce, nonce, plaintext, nil), nil
}

非对称加密:RSA 算法

非对称加密,有两把钥匙:公钥加密,私钥解密。公钥可以公开,私钥必须保密。这解决了对称加密最大的痛点——密钥分发问题。

但 RSA 有个硬伤:慢。你想想看,RSA-2048 加密 1KB 数据,比 AES-256 慢几千倍。所以实际项目中,没人用 RSA 直接加密大文件。怎么做?混合加密:用 RSA 加密 AES 密钥,再用 AES 加密数据。

我曾经帮一个团队排查性能问题,他们直接用 RSA 加密每一条日志记录……结果加密耗时比业务逻辑还长。改成混合加密后,性能提升了 40 倍。

避坑指南:RSA 的填充模式很重要。PKCS#1 v1.5 有历史漏洞,建议用 OAEP 填充。密钥长度至少 2048 位,4096 位更安全但性能下降明显。

// RSA-OAEP 加密示例
import (
    "crypto/rand"
    "crypto/rsa"
    "crypto/sha256"
)

func rsaEncrypt(plaintext []byte, pubKey *rsa.PublicKey) ([]byte, error) {
    return rsa.EncryptOAEP(sha256.New(), rand.Reader, pubKey, plaintext, nil)
}

哈希算法:SHA-256

哈希算法不是加密,是摘要。输入任意长度数据,输出固定长度哈希值。而且不可逆——你没法从哈希值反推出原文。

SHA-256 是 SHA-2 家族的一员,输出 256 位(32 字节)哈希值。它在存储系统里主要有两个用途:

  • 数据完整性校验:文件上传后计算哈希,下载时重新计算,对比是否一致
  • 密码存储:存密码的哈希值,而不是明文

但注意:不要直接用 SHA-256 存密码。为什么?因为彩虹表攻击。攻击者预计算常见密码的哈希值,一查就知道你的密码。正确的做法是加盐(salt)并多次迭代,比如用 bcrypt、scrypt 或 Argon2。

关键区别:SHA-256 是快速哈希,适合校验完整性;密码哈希需要慢速哈希(如 bcrypt),让暴力破解成本高到不可接受。

// SHA-256 计算文件哈希
import (
    "crypto/sha256"
    "io"
    "os"
)

func fileHash(path string) ([]byte, error) {
    f, err := os.Open(path)
    if err != nil {
        return nil, err
    }
    defer f.Close()
    h := sha256.New()
    if _, err := io.Copy(h, f); err != nil {
        return nil, err
    }
    return h.Sum(nil), nil
}

密钥管理基础

算法选得再好,密钥泄露一切白搭。密钥管理是加密体系中最薄弱的环节——我见过太多团队在算法上花大功夫,却把密钥写在配置文件里。

密钥管理有几个核心原则:

  • 密钥分级:主密钥加密工作密钥,工作密钥加密数据。这样即使工作密钥泄露,也只影响部分数据
  • 密钥轮换:定期更换密钥,降低单次泄露的影响范围
  • 硬件保护:高安全场景用 HSM(硬件安全模块)或 TPM(可信平台模块)存储密钥
  • 访问控制:密钥只能被授权服务访问,通过 KMS(密钥管理服务)统一管理
存储方式 安全等级 适用场景
环境变量 低 开发测试环境
配置文件(加密) 中 小型部署
KMS(如 AWS KMS / HashiCorp Vault) 高 生产环境
HSM 极高 金融、政务等高合规场景

我的经验:别自己写密钥管理逻辑。用现成的 KMS 或 Vault,它们已经处理了密钥轮换、审计日志、访问控制这些麻烦事。你只需要关注业务逻辑。

嗯,到这里加密基础就讲完了。记住一句话:算法是工具,密钥管理是防线。选对工具,守好防线,你的存储系统才能经得起实战考验。