# SHA256-RSA2048PSS **Repository Path**: zchhacker/SHA256-RSA2048PSS ## Basic Information - **Project Name**: SHA256-RSA2048PSS - **Description**: 基于 C 语言的 SHA256 哈希 + RSA2048-PSS 签名验证实现 - **Primary Language**: C - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 3 - **Created**: 2023-10-19 - **Last Updated**: 2026-06-02 ## Categories & Tags **Categories**: Uncategorized **Tags**: 算法 ## README # SHA256-RSA2048-PSS 签名验证 基于 C 语言的 SHA256 哈希 + RSA2048-PSS 签名验证实现,面向嵌入式 bootloader 安全模块(AUTOSAR SecM 风格)。 ## 算法流程 ``` 签名阶段(离线,如 OpenSSL) =========================== 原始数据 ──SHA256──→ 哈希值(32字节) ──RSA-PSS-签名──→ 签名(256字节) ↑ 私钥 验签阶段(本程序) ================== 原始数据 ──SHA256──→ 哈希值(32字节) ──┐ ├── 比较 ──→ 通过 / 失败 签名 ──RSA-公钥-解密──→ 恢复的哈希值 ──┘ ↑ 公钥 ``` ### RSA-PSS 验签详细过程 PSS(概率签名方案)通过加入随机 salt 防止确定性攻击。内部步骤如下: ``` 步骤 1: 输入 - hash: 原始数据的 SHA256 哈希(32字节) - signature: 私钥签名的数据(256字节) - public_key: RSA2048 模数 N + 公钥指数 e=65537 步骤 2: RSA 公钥运算 signature^e mod N → 编码消息(256字节) 步骤 3: PSS 解码(log 中两个 TRACE 值的来源) 3a. 从编码消息中提取 masked_seed 和 DB(数据块) 3b. MGF1 掩码生成: masked_seed ──与 MGF1(DB) 异或──→ seed 3c. 计算本地哈希(log 中 "RSA PSS hash computed" 行): H' = SHA256( 0x00*8 || 原始hash || salt ) ↑ ↑ 来自步骤1 从seed中提取 步骤 4: 比较 H'(本地计算) == H(签名中解密得到) 一致 → ret 0(通过) 不一致 → ret 1(失败) ``` log 中打印的两个哈希值含义: - `RSA PSS hash from signature`: 签名解密后嵌入的 H 值 - `RSA PSS hash computed`: 本地重新计算的 H' = SHA256(0x00*8 || hash || salt) - 这两个值**不是**原始数据的 SHA256,而是 PSS 编码后的哈希 ## 工程结构 ``` sha256-rsa2048/ ├── Test.c 主测试程序(双模式) ├── MakeBuild.bat 编译运行脚本 ├── Algorithm/ │ ├── Hash/Hash_256/ │ │ ├── Sha_256.c SHA256 实现 │ │ └── Sha_256.h │ ├── Rsa/ │ │ ├── Rsa2048.c RSA 大数运算 │ │ ├── Rsa2048.h │ │ ├── Rsa_Verify_Pss.c RSA-PSS 验签核心 │ │ ├── Rsa_Cfg.c 默认公钥(256字节) │ │ └── Rsa_Cfg.h │ ├── Crc/ │ │ ├── Cal.c CRC 实现 │ │ ├── Cal.h │ │ └── Cal_Cfg.h │ └── Aes/ │ ├── aes.c AES 实现 │ ├── aes_crypto.c │ └── CMAC_AES_128.c CMAC-AES-128 ├── Convert/ │ ├── ConvertDataType.c 十六进制/字符串转换工具 │ └── ConvertDataType.h ├── Other/ │ ├── SecM.c 安全模块(仅嵌入式 ECU 使用) │ ├── SecM.h │ ├── SecM_Cfg.c │ ├── SecM_Cfg.h │ ├── Std_Types.h AUTOSAR 标准类型 │ └── Platform_Types.h 平台类型定义 └── _keygen/ 生成的密钥文件(Mode 2 用) ├── private.pem RSA2048 私钥 ├── pubkey.der 公钥(DER 格式) ├── testdata.bin 测试数据文件 └── signature.bin 签名文件 ``` ## 编译 需要 GCC。编译脚本只编译算法模块(不包含 SecM): ```bat gcc Test.c Algorithm\Rsa\*.c Algorithm\Hash\Hash_256\*.c Convert\*.c -o Test.exe ``` 或使用批处理文件: ```bat .\MakeBuild.bat ``` ## 双模式说明 修改 Test.c 中的 `#define TEST_MODE` 切换模式: ### 模式 1 — 直接输入 ```c #define TEST_MODE 1 ``` 所有数值为硬编码字符串,使用 `Rsa_Cfg.c` 中的默认公钥。 ``` 输入: input_sha256 (64个十六进制字符 = 32字节 SHA256 哈希) 输入: input_signture (512个十六进制字符 = 256字节 RSA 签名) 密钥: Rsa_Cfg.c 中的 PublicbufDcDefault ``` 适用于已有 SHA256 哈希和签名的外部测试场景。 ### 模式 2 — 计算 SHA256 + 自定义密钥 ```c #define TEST_MODE 2 ``` 从原始数据计算 SHA256,使用自定义公钥和签名(如 OpenSSL 生成)。 ``` 输入: SduDataPtr (原始数据字节) 输入: input_rsa2048_pubkey (512个十六进制字符 = 256字节公钥模数 N) 输入: input_signture (512个十六进制字符 = 256字节签名) ``` 适用于测试完整流程:原始数据 → SHA256 → RSA-PSS 验签。 ## 模式 2 使用方法:生成密钥和签名 ### 第 1 步:生成 RSA2048 私钥 ```bash openssl genrsa -out private.pem 2048 ``` ### 第 2 步:准备测试数据 创建包含原始数据的二进制文件。例如 `{0xFF, 0xFF}`: ```powershell # PowerShell [byte[]]$bytes = @(0xFF, 0xFF) [System.IO.File]::WriteAllBytes('testdata.bin', $bytes) ``` ### 第 3 步:对数据签名 ```bash openssl dgst -sha256 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1 -sign private.pem -out signature.bin testdata.bin ``` 参数说明: - `-sha256`:使用 SHA256 哈希 - `-sigopt rsa_padding_mode:pss`:使用 PSS 填充(本实现要求) - `-sigopt rsa_pss_saltlen:-1`:salt 长度 = 哈希长度(32字节),对应代码中的 `RSA_SALT_LEN_ANY` ### 第 4 步:提取签名为十六进制字符串 ```powershell # PowerShell $sig = [System.IO.File]::ReadAllBytes('signature.bin') $hex = ($sig | ForEach-Object { $_.ToString("X2") }) -join '' Write-Host $hex ``` 将输出复制到 Test.c 的 `input_signture`。 ### 第 5 步:提取公钥模数为十六进制字符串 ```bash openssl rsa -in private.pem -modulus -noout ``` 输出:`Modulus=BCCF0CB9E5F438F0...` 将 `Modulus=` 后面的十六进制字符串复制到 Test.c 的 `input_rsa2048_pubkey`。 ### 第 6 步:编译运行 ```bat gcc Test.c Algorithm\Rsa\*.c Algorithm\Hash\Hash_256\*.c Convert\*.c -o Test.exe Test.exe ``` 期望输出: ``` [Mode 2] Compute SHA256 from raw data Plaintext is: ff ff Sha256 is: ca 2f d0 0f ... RSA PSS hash from signature: c9 7e ee 59 ... RSA PSS hash computed: c9 7e ee 59 ... ret 0 ``` `ret 0` = 验签通过。 ## 公钥格式 公钥为 RSA 模数 N(256字节,大端序)。公钥指数固定为 e=65537。 `Rsa_Cfg.c` 中(模式 1): ```c const uint8 PublicbufDcDefault[256] = { 0xd3, 0xaa, 0x00, ... }; ``` 模式 2 中,公钥以十六进制字符串在运行时提供。 ## 缺失文件说明 `SecM.c`/`SecM.h` 依赖 `fl.h`(Flash 驱动)和 `Appl.h`(应用层接口)。这些是嵌入式平台文件,未包含在本仓库中,它们不会影响SHA256+RSA算法的功能。