资讯动态

ESP32 Hash 库校验测试全解析:基于 NIST/RFC 已知答案向量的 MD5、SHA-1/2/3 与 PBKDF2-HMAC 验证指南

发布时间:2026/9/14 4:43:15 来源:尧图企业网站定制
ESP32 Hash 库校验测试全解析基于 NIST/RFC 已知答案向量的 MD5、SHA-1/2/3 与 PBKDF2-HMAC 验证指南【免费下载链接】arduino-esp32Arduino core for the ESP32 family of SoCs项目地址: https://gitcode.com/GitHub_Trending/ar/arduino-esp32本篇指南以 arduino-esp32 仓库中 tests/validation/hash/README.md 为骨架结合 hash.ino 测试源码与 libraries/Hash 库实现完整讲解 Hash 校验测试套件的目标、测试用例矩阵、标准依据、运行环境要求以及 HEXBuilder、MD5、SHA-1/2/3、PBKDF2-HMAC 各 Builder 的 API 用法与底层原理。读完本文你将能独立运行该校验测试、复现每个已知答案向量并在自己的固件工程中正确选用和调用 ESP32 Hash 库。一、测试套件概述用权威已知答案向量锁定正确性tests/validation/hash目录下共有三个文件README.md测试套件的说明文档即本文主体来源hash.ino基于 Unity 框架的固件端测试程序包含全部测试函数与setup()注册逻辑test_hash.pypytest 侧的自动化验证脚本通过dut.expect_unity_test_output(timeout120)读取 DUTDevice Under Test被测设备串口输出的 Unity 测试结果。该套件的核心使命是验证 Hash 库libraries/Hash覆盖的对象包括被测组件所在位置HEXBuilder十六进制/字节转换cores/esp32/HEXBuilder.hMD5Buildercores/esp32/MD5Builder.hSHA1Builderlibraries/Hash/src/SHA1Builder.hSHA2BuilderSHA-224/256/384/512libraries/Hash/src/SHA2Builder.hSHA3BuilderSHA3-224/256/384/512libraries/Hash/src/SHA3Builder.hPBKDF2_HMACBuilderlibraries/Hash/src/PBKDF2_HMACBuilder.hHashBuilder统一抽象基类cores/esp32/HashBuilder.h所有断言均使用已知答案向量known-answer test vectors即给定输入必然得到固定输出的公开标准值标准来源为NIST FIPS 180-4SHA-1、SHA-224/256/384/512NIST FIPS 202SHA3-224/256/384/512RFC 1321MD5RFC 6070PBKDF2-HMAC基于 HMAC-SHA1/SHA-256 的密码派生。使用权威标准向量而不是自造数据的意义在于一旦实现与标准算法存在任何偏差常量错误、字节序错误、填充错误、迭代次数错误测试立即失败从而保证库输出与 PC 端openssl、sha256sum等标准工具完全一致。二、测试用例矩阵五大模块 60 个断言hash.ino中所有测试函数在setup()内通过RUN_TEST(...)逐个注册执行完整矩阵如下。2.1 HEXBuilder 十六进制工具10 个用例测试函数验证点关键断言test_hex_bytes2hex_string字节数组转十六进制String{0x48,0x65,0x6c,0x6c,0x6f}→48656c6c6ftest_hex_bytes2hex_buffer写入 char 缓冲区并返回长度输出48656c6c6f返回 11含\0test_hex_hex2bytes十六进制串转回字节数组48656c6c6f→{0x48,...,0x6f}test_hex_is_valid合法十六进制串判定0123456789abcdefABCDEF为真test_hex_is_invalid非法输入拒绝xyz为假test_hex_roundtripbytes→hex→bytes 往返无损{0xDE,0xAD,0xBE,0xEF,0x42}还原一致test_hex_empty_bytes2hex空输入空输入产生空串test_hex_empty_hex2bytes空串解码输出缓冲区保持原值0xFF不被触碰test_hex_is_valid_with_len带长度参数的局部校验isHexString(abcdefXYZ,6)为真(…,9)为假test_hex_hex2bytes_string_overloadString对象重载String(cafe)→{0xCA,0xFE}从 HEXBuilder.h 可以看到该类的静态 API 形态hex2bytes同时提供String与const char*两个重载bytes2hex提供返回String与写入char*缓冲区两种形式isHexString也支持(const char*, size_t len)的局部长度判定——这正是测试中test_hex_is_valid_with_len所覆盖的分支。注意bytes2hex缓冲区版本返回的长度包含结尾\0如 5 字节输入返回 11调用方需按len*21申请缓冲。2.2 MD5RFC 132113 个用例测试函数验证点关键断言摘要十六进制test_md5_empty空输入d41d8cd98f00b204e9800998ecf8427etest_md5_abcabc900150983cd24fb0d6963f7d28e17f72test_md5_message_digestmessage digestf96b697d7cb7938d525a2f31aaf161d0test_md5_alphabet全小写字母表c3fcd3d76192e4007dfb496cca67e13btest_md5_hash_size摘要长度16 字节test_md5_getbytes原始字节输出与期望 16 字节逐字节相等test_md5_getchars十六进制字符输出与toString()一致test_md5_multi_chunk分块add(a)add(bc)与一次性abc相同test_md5_add_stringString对象输入同上test_md5_add_hex_string十六进制串输入616263即abc→ 同上test_md5_add_hex_string_obj十六进制String对象输入同上test_md5_resetbegin()重置后重算second→a9f0e61a137d86aa9db53465e0801612test_md5_add_stream从 Stream 输入StreamString(Hello, World!)→65a8e27d8879283831b664bd8b7f0ad4其中test_md5_multi_chunk与test_md5_add_hex_string等用例共同印证了HashBuilder基类HashBuilder.h提供的统一输入通道add(const uint8_t*, size_t)、add(const char*)、add(String)、addHexString(const char*)、addHexString(String)以及流式addStream(Stream, size_t)。分块与一次性输入摘要一致验证了内部增量缓冲的正确性。2.3 SHA-1FIPS 180-44 个用例测试函数验证点关键断言test_sha1_empty空输入da39a3ee5e6b4b0d3255bfef95601890afd80709test_sha1_abcabca9993e364706816aba3e25717850c26c9cd0d89dtest_sha1_hash_size摘要长度20 字节SHA1_HASH_SIZE见 SHA1Builder.htest_sha1_multi_chunk分块abc与abc一致2.4 SHA-2 家族SHA-224/256/384/512FIPS 180-420 个用例算法测试函数验证点关键断言SHA-224test_sha224_empty空输入d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42ftest_sha224_abcabc23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7test_sha224_hash_size摘要长度28 字节SHA-256test_sha256_empty空输入e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855test_sha256_abcabcba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015adtest_sha256_nist_two_block两分组 NIST 向量abcdbc…nopq→248d6a61…bdb06c1test_sha256_hash_size摘要长度32 字节test_sha256_multi_chunk分块输入与abc一致test_sha256_add_hex_string十六进制输入616263→ 同abctest_sha256_getbytes原始字节输出与 32 字节期望值逐字节相等test_sha256_resetbegin()重置重算second→16367aac…c44c7c4test_sha256_add_streamStream 输入Hello, World!→dffd6021…2986fSHA-384test_sha384_empty空输入38b060a7…98b95btest_sha384_abcabccb00753f…4c825a7test_sha384_hash_size摘要长度48 字节test_sha384_multi_chunk分块输入与abc一致test_sha384_nist_two_block两分组 NIST 向量abcdefgh…nopqrstu→09330c33…746039SHA-512test_sha512_empty空输入cf83e135…7da3etest_sha512_abcabcddaf35a1…54ca49ftest_sha512_hash_size摘要长度64 字节test_sha512_multi_chunk分块输入与abc一致test_sha512_nist_two_block两分组 NIST 向量abcdefgh…nopqrstu→8e959b75…4be909从 SHA2Builder.h 可以看到实现架构一个SHA2Builder基类承载 SHA-224/256/384/512 的全部状态与逻辑state_32[8]用于 SHA-224/256state_64[8]用于 SHA-384/512block_size分别为 64 与 128 字节再通过SHA224Builder、SHA256Builder、SHA384Builder、SHA512Builder四个子类以构造参数传入各自hash_size即可实例化。其构造函数依据hash_size自动选择算法族SHA2Builder.cpp28/32 字节走 SHA-256 族块大小 6448/64 字节走 SHA-512 族块大小 128。calculate()中的pad()实现了 Merkle–Damgård 填充先补0x80再补零最后按 64 位SHA-256 族或 128 位SHA-512 族长度字段写入总比特数SHA2Builder.cpp。2.5 SHA-3 家族SHA3-224/256/384/512FIPS 20212 个用例算法测试函数验证点关键断言SHA3-224test_sha3_224_empty空输入6b4e0342…5a6bc7test_sha3_224_abcabce642824c…46fdftest_sha3_224_hash_size摘要长度28 字节SHA3-256test_sha3_256_empty空输入a7ffc6f8…0f8434atest_sha3_256_abcabc3a985da7…41153132test_sha3_256_hash_size摘要长度32 字节test_sha3_256_multi_chunk分块输入与abc一致SHA3-384test_sha3_384_empty空输入0c63a75b…5d5f004test_sha3_384_abcabcec014982…8376d25test_sha3_384_hash_size摘要长度48 字节SHA3-512test_sha3_512_empty空输入a69f73cc…81dcd26test_sha3_512_abcabcb751850b…4eec53f0test_sha3_512_hash_size摘要长度64 字节从 SHA3Builder.h 可以看出 SHA-3 与 SHA-2 的结构性差异SHA-3 基于 Keccak 海绵结构内部状态为 1600 位uint64_t state[25]即SHA3_STATE_SIZE200 字节每个变体使用不同的吸收速率rate——SHA3-224 为 144 字节、SHA3-256 为 136、SHA3-384 为 104、SHA3-512 为 72对应SHA3_*_RATE宏。keccak_f置换与pad()共同完成海绵结构的吸收与挤出SHA3_224Builder等子类同样通过向基类构造函数传入各自hash_size实现SHA3Builder.h。FIPS 202 的向量断言保证了 Keccak-f[1600] 置换、填充0x06域分隔 0x80与速率选择的正确性。2.6 PBKDF2-HMACRFC 60705 个用例测试函数验证点关键断言test_pbkdf2_sha1_c1HMAC-SHA11 次迭代password/salt→0c60c80f961f0e71f3a9b524af6012062fe037a6test_pbkdf2_sha1_c2HMAC-SHA12 次迭代→ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957test_pbkdf2_sha256_c1HMAC-SHA2561 次迭代→120fb6cffcf8b32c43e7225256c4f837a86548c92ccc35480805987cb70be17btest_pbkdf2_sha1_c4096HMAC-SHA14096 次迭代→4b007901b765489abead49d926f721d065a429c1test_pbkdf2_setters构造后通过 setter 配置SHA-256/passwd/NaCl/1 次 →33044695…9c36952ctest_pbkdf2_sha1_c1/c2/c4096三组数据正是 RFC 6070 第 2 节的经典向量test_pbkdf2_sha1_c4096还验证了 4096 次迭代时 HMAC 循环的计数与中间状态累积正确性。test_pbkdf2_setters则覆盖了 PBKDF2_HMACBuilder.h 中的配置接口setHashAlgorithm(HashBuilder*)支持传入 SHA1Builder、SHA2Builder 等任意HashBuilder派生对象实现 HMAC 算法可插拔、setPassword(...)、setSalt(...)、setIterations(uint32_t)。默认迭代次数为 10000构造函数签名PBKDF2_HMACBuilder(HashBuilder *hash, String password , String salt , uint32_t iterations 10000)默认派生密钥长度为底层 Hash 的摘要长度getHashSize()返回derivedKeyLen。三、边界与压力用例填充边界与大输入测试套件还专门覆盖了哈希算法最容易出错的填充边界与大输入场景测试函数输入规模验证意图test_sha256_55bytes55 字节恰好差 1 字节触发填充块55 字节 块大小 64 − 8 长度字段 − 1 个0x80test_sha256_56bytes56 字节56 字节需额外补一个完整填充块test_sha384_112bytes112 字节SHA-384 块大小 128 的填充边界test_sha512_112bytes112 字节SHA-512 块大小 128 的填充边界test_sha256_10000a100 个 100 字节块 10,000 个a跨多块长输入的增量吸收正确性期望27dd1f61…4b71155/56 字节用例恰好覆盖pad()中填充后放不下长度字段则补块再填的分支SHA2Builder.cpp10,000 个a的用例则验证add()在buffer_size 0时先处理残留缓冲、再整块循环、最后缓存尾部数据的增量逻辑SHA2Builder.cpp。这两个边界恰好是许多简易实现容易出错的盲区因此单独成例。四、运行环境与执行方式4.1 运行要求按 README 的 Requirements 一节本测试套件的运行条件为硬件任意 ESP32 系列芯片ESP32 / ESP32-S2 / ESP32-S3 / ESP32-C3 / ESP32-C6 等均适用Wokwi支持可在 Wokwi 在线模拟器中直接运行该固件测试QEMU不支持。4.2 固件端运行方式将 tests/validation/hash 目录作为 Arduino sketch 打开并烧录到 ESP32 开发板。固件以 115200 波特率初始化串口并等待Serial就绪然后执行UNITY_BEGIN()与全部RUN_TEST(...)注册的用例最终UNITY_END()输出 Unity 框架的标准测试报告逐例 PASS/FAIL 与汇总。loop()为空函数测试只在setup()阶段运行一次。4.3 自动化测试方式配合 test_hash.py 通过 pytest 接入仓库的自动化测试框架tests/validation 目录下可见配套的conftest.py、pytest.ini与requirements.txt。其核心只有一行def test_hash(dut): dut.expect_unity_test_output(timeout120)即等待并解析 DUT 串口输出的 Unity 测试结果timeout120表示最多等待 120 秒覆盖 PBKDF2 4096 次迭代等耗时用例。这意味着该套件可以在 CI 中批量对多款 ESP32 变体执行回归验证。五、从测试到实战Builder API 使用范式测试代码即最佳示例。所有 Builder 共享统一的生命周期范式#include MD5Builder.h #include SHA1Builder.h #include SHA2Builder.h #include SHA3Builder.h #include PBKDF2_HMACBuilder.h // 1. 实例化不同摘要长度选择对应 Builder 类 MD5Builder md5; SHA1Builder sha1; SHA256Builder sha256; // SHA224Builder / SHA384Builder / SHA512Builder 同理 SHA3_256Builder sha3; // SHA3_224Builder / SHA3_384Builder / SHA3_512Builder 同理 // 2. begin() 初始化重置内部状态 sha256.begin(); // 3. 输入数据可多次 add支持分块 / String / 十六进制串 / Stream sha256.add(abc); sha256.addHexString(616263); // 等价于 add(abc) sha256.addStream(ss, ss.available()); // Stream 输入 // 4. calculate() 完成计算 sha256.calculate(); // 5. 取结果toString() / getChars() / getBytes() String hex sha256.toString(); // ba7816bf... char buf[65]; sha256.getChars(buf); uint8_t raw[32]; sha256.getBytes(raw); // 6. getHashSize() 返回摘要字节数 size_t n sha256.getHashSize(); // 32PBKDF2-HMAC 的两种配置方式构造参数 / setter可直接参照 libraries/Hash/examples/PBKDF2_HMAC/PBKDF2_HMAC.ino 中的四种用法// 方式 A构造时传入全部参数 SHA1Builder sha1; PBKDF2_HMACBuilder pbkdf2(sha1, password, salt, 1); pbkdf2.begin(); pbkdf2.calculate(); Serial.println(pbkdf2.toString()); // 0c60c80f... // 方式 B构造后通过 setter 配置 SHA256Builder sha256; PBKDF2_HMACBuilder pbkdf2b(NULL); pbkdf2b.setHashAlgorithm(sha256); pbkdf2b.setPassword(passwd); pbkdf2b.setSalt(NaCl); pbkdf2b.setIterations(1); pbkdf2b.begin(); pbkdf2b.calculate(); // 方式 C密码与盐使用字节数组非文本场景 uint8_t password[] {0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64}; // password uint8_t salt[] {0x73, 0x61, 0x6c, 0x74}; // salt pbkdf2.setPassword(password, sizeof(password)); pbkdf2.setSalt(salt, sizeof(salt)); pbkdf2.setIterations(1000);该库在library.properties中声明为categorySecurity、architecturesesp32、版本 3.3.11随 Arduino ESP32 核心一同发布。库还附带 HEX、MD5、SHA1、SHA2、SHA3、SHA3Stream、PBKDF2_HMAC 共 7 个示例libraries/Hash/examples可用于快速上手与人工比对验证。六、在固件工程中复用测试用例的建议移植校验将 hash.ino 中任意用例的断言值如ba7816bf...与 PC 端echo -n abc | sha256sum、openssl dgst -sha3-256输出比对可快速确认板端实现与标准工具一致回归基线在修改或替换哈希实现后直接以本套件为回归基线——尤其关注 55/56 字节填充边界、两分组 NIST 向量与 10,000 字节大输入用例这三类用例最能暴露增量缓冲与填充逻辑缺陷安全场景选型MD5/SHA-1 仅适用于完整性校验等非安全场景需要抗碰撞安全时选用 SHA-256 及以上需要密码派生时使用 PBKDF2_HMAC 并合理选择迭代次数RFC 6070 向量仅验证正确性生产环境建议远高于 4096并注意 ESP32 上的计算耗时CI 集成将test_hash.py的dut.expect_unity_test_output(timeout120)模式接入自动构建即可对每款 ESP32 变体执行全量向量回归。七、小结tests/validation/hash校验测试以 NIST FIPS 180-4、FIPS 202、RFC 1321、RFC 6070 的权威已知答案向量为核心对 HEXBuilder、MD5Builder、SHA-1/2/3 系列 Builder 与 PBKDF2-HMAC 进行了系统验证既有覆盖每个算法的空输入/标准输入/摘要长度/分块输入/重置/流输入等常规用例也有填充边界与大输入等易错场景以及 4096 次迭代的压力向量。它既是 Hash 库正确性的体检报告也是开发者理解 ESP32 上各类哈希与密钥派生 API 的最佳入门教材——测试中每一个断言值都可以直接复用到自己的固件工程中作为自校验基线。【免费下载链接】arduino-esp32Arduino core for the ESP32 family of SoCs项目地址: https://gitcode.com/GitHub_Trending/ar/arduino-esp32创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价