数字签名用于**验证数据来源的真实性、完整性和不可否认性**,其核心是使用私钥签名、公钥验签,适用于身份认证、文档签署、软件分发等场景 数字签名的应用通常不包括C. 密码存储✅理由数字签名用于验证数据来源的真实性、完整性和不可否认性其核心是使用私钥签名、公钥验签适用于身份认证、文档签署、软件分发等场景。而密码存储应采用加盐哈希如 bcrypt、scrypt、Argon2等单向不可逆方式目的是防止明文泄露和彩虹表攻击若用数字签名存储密码不仅违背设计目的签名可被公钥验证但不应“可验证原始密码”还可能引入私钥管理风险且无法实现密码的单向保护。常见数字签名典型应用包括SSL/TLS 证书验证服务器身份电子合同与政务签章法律效力保障APK/APP代码签名Android/iOS 应用完整性校验软件发布签名如 Linux 内核模块、GPG 签名S/MIME 或 PGP 电子邮件签名发件人身份认证❌ 密码存储不属于数字签名的应用范畴属于密码学中的密钥派生与哈希保护领域。数字签名不能用于密码存储根本原因在于二者的设计目标、安全模型和使用方式存在本质冲突1. 设计目标不同数字签名解决身份认证、数据完整性与不可否认性问题。它要求“可验证”——任何人持有公钥即可验证签名是否由对应私钥生成但不隐藏原始消息内容签名对象通常是明文摘要而非保密数据。密码存储核心目标是单向保护与抗逆向——即使数据库泄露攻击者也无法从存储值恢复原始密码。这要求不可逆性、抗碰撞性、抗预计算如彩虹表且必须引入随机性加盐。2. 安全模型冲突数字签名依赖私钥保密、公钥公开验签过程天然暴露“该消息曾被某私钥签署”若用它“存储密码”相当于将“密码是否匹配”变成一个可被任意方拥有公钥者主动验证的公开操作严重违背最小权限与保密原则。更危险的是若攻击者获取公钥和签名值虽不能直接恢复密码但可进行离线暴力/字典验证即猜一个密码 → 计算其摘要 → 用公钥验签是否匹配而哈希加盐方案通过慢哈希如 bcrypt大幅增加验证成本签名则无此防护。3. 技术机制不匹配数字签名 ≠ 加密签名是对消息摘要如 SHA-256 值的私钥运算不改变原始密码的可枚举性它不提供密钥派生KDF、不引入计算延迟、无盐值绑定无法抵御批量爆破。哈希加盐方案如bcrypt(password, salt, cost)✅ 强制唯一盐值防彩虹表✅ 可调代价因子防暴力加速✅ 单向函数无法从输出反推输入✅ 专为密码场景标准化OWASP 推荐✅ 正确做法密码存储应使用专用密钥派生函数KDF如 bcrypt、scrypt、Argon2 或 PBKDF2而数字签名仅用于“证明某主体对某数据的认可”如签署登录挑战、证书、交易等。# ❌ 错误示例用 RSA 签名“存储”密码极度危险fromcryptography.hazmat.primitives.asymmetricimportpadding,rsafromcryptography.hazmat.primitivesimporthashes private_keyrsa.generate_private_key(public_exponent65537,key_size2048)passwordb123456signatureprivate_key.sign(password,padding.PKCS1v15(),hashes.SHA256())# 危险签名暴露验证入口# ✅ 正确示例用 bcrypt 安全存储密码importbcrypt passwordb123456saltbcrypt.gensalt(rounds12)hashedbcrypt.hashpw(password,salt)# 单向、加盐、慢计算