3. 安全存储对称密钥

安全存储对称密钥 学习卡片

任务目标

将AES-128对称密钥安全导入HSM(硬件安全模块),并配置访问控制策略,确保该密钥仅可用于加密/解密操作,且任何情况下不可从HSM中导出。本案例使用OpenSSL的PKCS#11接口与SoftHSM模拟器完成闭环验证。

环境依赖

  • SoftHSMv2(模拟HSM设备)
  • OpenSC(提供pkcs11-tool)
  • OpenSSL(用于生成AES密钥材料)

安装命令(Ubuntu/Debian):apt install softhsm opensc openssl

实现步骤与代码

1. 初始化HSM 并生成AES密钥

# 初始化SoftHSM的(仅首次)
softhsm2-util --init- --slot 0 --label "demo" --pin 1234 --so-pin 5678

# 生成随机AES-128密钥材料(16字节)
dd if=/dev/urandom of=aes_key.bin bs=16 count=1

# 将密钥导入HSM,设置不可导出属性(CKA_EXTRACTABLE=false)
pkcs11-tool --module /usr/lib/softhsm/libsofthsm2.so \
  --slot 0 --login --pin 1234 \
  --write-object aes_key.bin --type secret-key \
  --key-type AES --id 01 --label "aes_app_key" \
  --usage-decrypt --usage-encrypt \
  --extractable=false

2. 验证密钥不可导出

# 尝试导出密钥(应失败)
pkcs11-tool --module /usr/lib/softhsm/libsofthsm2.so \
  --slot 0 --login --pin 1234 \
  --read-object --id 01 --type secret-key --output export_test.bin

# 预期输出:error: PKCS11 function C_GetAttributeValue failed: rv = CKR_ATTRIBUTE_SENSITIVE (0x11)

3. 验证密钥可用于加密操作

# 使用导入的密钥加密测试数据
echo "confidential data" > plaintext.txt

pkcs11-tool --module /usr/lib/softhsm/libsofthsm2.so \
  --slot 0 --login --pin 1234 \
  --encrypt --id 01 --mechanism AES-CBC \
  --input-file plaintext.txt --output-file ciphertext.bin

# 解密验证
pkcs11-tool --module /usr/lib/softhsm/libsofthsm2.so \
  --slot 0 --login --pin 1234 \
  --decrypt --id 01 --mechanism AES-CBC \
  --input-file ciphertext.bin --output-file decrypted.txt

# 对比明文是否一致
diff plaintext.txt decrypted.txt && echo "PASS: 加解密闭环验证成功"

访问控制策略说明

上述命令中关键属性含义:

  • --extractable=false:设置CKA_EXTRACTABLE为false,密钥材料无法通过C_GetAttributeValue或C_Unwrap导出
  • --usage-encrypt/--usage-decrypt:设置CKA_ENCRYPT和CKA_DECRYPT为true,限制密钥仅用于加解密
  • --login --pin 1234:要求会话登录,未认证用户无法使用该密钥

验证判定标准

检查项通过条件
密钥导入pkcs11-tool列出对象时能看到id=01的AES密钥
不可导出执行read-object命令返回CKR_ATTRIBUTE_SENSITIVE错误
可用性加密后能成功解密,且diff明文一致
访问控制未提供PIN时执行加密操作返回CKR_USER_NOT_LOGGED_IN

若以上四项全部满足,则确认AES对称密钥已安全导入HSM且不可导出,访问控制策略生效。