You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用CryptoPP通过公钥验证带签名PNG文件的正确性?

提取ECDSA签名并验证文件有效性的方法

核心逻辑

老师生成md5.png的规则是:原始hello.png的二进制数据直接拼接ECDSA<ECP,SHA1>签名数据。所以md5.png的前半段完全等于hello.png的内容,后半段就是签名。只需先确定原始文件的字节长度,就能拆分出签名并验证。

具体操作步骤

1. 获取原始文件的字节长度

先拿到hello.png的准确大小:

  • Linux/macOS执行命令:
    ls -l hello.png | awk '{print $5}'
    
  • Windows执行命令:
    dir hello.png
    

记录下这个数值(比如假设为12345字节)。

2. 从md5.png中拆分出签名

用工具把md5.png的前N字节(N为原始文件长度)分离出来(可选,用于验证和原始文件一致),剩余部分就是签名:

  • Linux/macOS用dd命令:
    # 提取原始图片内容(可选验证用)
    dd if=md5.png of=extracted_hello.png bs=1 count=12345
    # 提取签名数据到文件
    dd if=md5.png of=signature.bin bs=1 skip=12345
    
  • Windows用PowerShell:
    $fileBytes = Get-Content md5.png -Raw -Encoding Byte
    $originalLen = 12345
    # 提取签名并保存
    $signatureBytes = $fileBytes[$originalLen..($fileBytes.Length-1)]
    Set-Content signature.bin -Value $signatureBytes -Encoding Byte
    

3. 用CryptoPP验证签名

编写C++代码,使用老师提供的公钥验证原始文件和签名的匹配性:

#include <iostream>
#include <fstream>
#include <cryptopp/eccrypto.h>
#include <cryptopp/sha.h>
#include <cryptopp/base64.h>
#include <cryptopp/files.h>

using namespace CryptoPP;

int main(int argc, char* argv[]) {
    if (argc != 4) {
        std::cerr << "Usage: ./verify <public_key_file> <original_file> <signature_file>" << std::endl;
        return 1;
    }

    // 加载Base64编码的公钥
    ECDSA<ECP, SHA1>::PublicKey publicKey;
    FileSource pubFile(argv[1], true, new Base64Decoder);
    publicKey.Load(pubFile);

    // 读取原始文件二进制内容
    std::string originalData;
    FileSource origFile(argv[2], true, new StringSink(originalData));

    // 读取签名二进制数据
    std::string signature;
    FileSource sigFile(argv[3], true, new StringSink(signature));

    // 执行签名验证
    ECDSA<ECP, SHA1>::Verifier verifier(publicKey);
    bool isValid = verifier.VerifyMessage(
        reinterpret_cast<const byte*>(originalData.data()), originalData.size(),
        reinterpret_cast<const byte*>(signature.data()), signature.size()
    );

    std::cout << (isValid ? "Signature is valid!" : "Signature is invalid!") << std::endl;
    return isValid ? 0 : 1;
}

编译时链接CryptoPP库:

g++ verify.cpp -o verify -lcryptopp

对每个md5.png重复步骤2和3,找到验证输出Signature is valid!的文件即可。

注意事项

  • 确保hello.png未被修改,否则所有验证都会失败。
  • ECDSA<ECP,SHA1>的签名长度固定(对应所选椭圆曲线的大小,比如P-256曲线签名为64字节),若拆分出的签名长度不符,说明原始文件长度取值错误。

内容的提问来源于stack exchange,提问作者abcd1211231

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 13:50:21