资讯详情

libcrypto 别忽略这行代码,否则加密会失败

📅 2026/9/15 8:25:43 | 华诺云谱 👁 阅读
libcrypto 别忽略这行代码,否则加密会失败
代码对比/* 第一组3行显式设置两个哈希 */ EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING); EVP_PKEY_CTX_set_rsa_oaep_md(ctx, EVP_sha256()); // OAEP 哈希 SHA-256 EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, EVP_sha256()); // MGF1 哈希 SHA-256 ← 多了这行 /* 第二组2行只设置 OAEP 哈希 */ EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING); EVP_PKEY_CTX_set_rsa_oaep_md(ctx, EVP_sha256()); // OAEP 哈希 SHA-256 // MGF1 哈希 ???未显式设置RSA OAEP 的两个哈希算法RSA OAEP 填充RFC 8017 / PKCS#1 v2.2内部有两个独立的哈希算法OAEP 编码结构 ┌─────────────────────────────────────────────────────┐ │ Hash(L) │ PS(全零) │ 0x01 │ M(消息) │ ← 用 oaep_md 计算 Hash(L) │ (hLen) │ │ │ │ ├─────────────────────────────────────────────────────┤ │ DB Hash(L) || PS || 0x01 || M │ │ maskedDB DB XOR MGF(seed, mLen) │ ← 用 mgf1_md 计算 MGF │ maskedSeed seed XOR MGF(maskedDB, hLen) │ ← 用 mgf1_md 计算 MGF └─────────────────────────────────────────────────────┘OAEP 编码结构关键点这两个哈希是独立的可以相同也可以不同。标准允许 oaep_md ≠ mgf1_md但实际工程中通常设为相同。第二组代码的 MGF1 哈希到底是什么这取决于OpenSSL 版本OpenSSL 版本只设 oaep_mdSHA-256 时mgf1_md 的值1.0.2 及更早保持默认SHA-1不跟随 oaep_md1.1.0 / 1.1.1保持默认SHA-1不跟随 oaep_md3.0文档说通常跟随 oaep_md但不保证建议显式设置结论第二组代码在大多数 OpenSSL 版本中MGF1 哈希仍然是SHA-1而不是你期望的 SHA-256/* 第二组代码实际效果OpenSSL 1.1.x oaep_md SHA-256 设置的 mgf1_md SHA-1 默认值你没设置 */这是一个非常隐蔽的坑——你以为用了 SHA-256实际上 MGF1 还在用 SHA-1。实际影响跨平台解密失败场景1和对端都用第一组代码显式 SHA-256 SHA-256加密端oaepSHA-256, mgf1SHA-256解密端oaepSHA-256, mgf1SHA-256结果 解密成功场景2加密端用第一组解密端用第二组OpenSSL 1.1.x加密端oaepSHA-256, mgf1SHA-256解密端oaepSHA-256, mgf1SHA-1 ← MGF1 不匹配结果 解密失败padding check failed / RSA_OAEP_DECRYPT_ERROR场景3和 Java / Python / 嵌入式设备交互语言/平台OAEP 默认配置注意事项Java JCEOAEPWithSHA-256AndMGF1Padding→ oaepSHA-256, mgf1SHA-1Java 的 MGF1 默认是 SHA-1必须用OAEPParameterSpec显式指定 MGF1SHA-256Python cryptographyOAEP(mgfMGF1(algorithmSHA256()),algorithmSHA256())必须显式指定两者嵌入式 mbedTLSMBEDTLS_RSA_PKCS_V21 hash_id两个哈希通常绑定为同一个OpenSSL 命令行openssl pkeyutl -encrypt -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha256 -pkeyopt rsa_mgf1_md:sha256必须两个都指定Java 的坑最大OAEPWithSHA-256AndMGF1Padding 这个名字看起来两个都是 SHA-256但实际上 MGF1 默认是 SHA-1必须这样写OAEPParameterSpec spec new OAEPParameterSpec( SHA-256, MGF1, MGF1ParameterSpec.SHA256, // ← 必须显式指定 MGF1SHA-256 PSource.PSpecified.DEFAULT );为什么第一组是最佳实践1. 行为确定不依赖 OpenSSL 版本显式设置两个哈希无论 OpenSSL 1.0.2 / 1.1.x / 3.x行为完全一致。2. 跨平台兼容性可控和 Java/Python/嵌入式设备联调时双方明确约定 oaepSHA-256, mgf1SHA-256不会出现我这边是 SHA-256你那边 MGF1 是 SHA-1的诡异问题。3. 安全强度一致如果 oaepSHA-256 但 mgf1SHA-1整体安全强度被 SHA-1 拖后腿。PCI PTS v7.0 要求设备安全功能 ≥128-bitSHA-1160-bit 但已被攻破不满足要求必须全部用 SHA-256。4. 审计友好安全审计时显式设置的代码一目了然只设一个的代码需要审计员去查 OpenSSL 版本默认值容易遗漏。pos项目中的建议涉及 RSA 的场景TR-34 远程密钥加载、脱机 PIN 加密等统一用第一组写法/*RSA OAEP 标准配置 */ EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING); EVP_PKEY_CTX_set_rsa_oaep_md(ctx, EVP_sha256()); EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, EVP_sha256()); // 必须显式设置检查清单所有 RSA 加密/解密都用 OAEP禁止 PKCS#1 v1.5oaep_md 和 mgf1_md 都显式设置为 SHA-256和对端银联/TMS/密钥注入系统确认双方配置一致Java 端用 OAEPParameterSpec 显式指定 MGF1SHA-256密钥长度 ≥2048-bitPCI PTS v7.0 建议 3072-bit 或 ECC P-256总结对比项第一组3行第二组2行OAEP 哈希SHA-256显式SHA-256显式MGF1 哈希SHA-256显式取决于 OpenSSL 版本通常是 SHA-1行为确定性跨版本一致依赖默认值跨平台兼容可控容易和 Java/Python 不匹配安全强度全 SHA-256MGF1 可能是 SHA-1PCI PTS v7.0合规可能不合规SHA-1推荐度推荐不推荐一句话第一组多的那行 EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, EVP_sha256()) 不是多余的它确保 MGF1 掩码生成函数也用 SHA-256避免 OpenSSL 默认值带来的隐蔽兼容性和安全问题。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。