c++ 如何使用cryptopp验证png文件的公钥?

mwg9r5ms  于 2023-06-07  发布在  其他
关注(0)|答案(1)|浏览(150)

我的老师给了我PublicKey,hello.png(原始文件)和五个md5.png文件(图像+签名)。问我哪个md5.png文件的签名与原始文件一致。
这是c++的代码,我的老师使用crptopp libabry将png文件加载到base64,然后对它们进行签名。之后,将图像和签名相加为新文件名md5.png:

int main(int argc, char* argv[])
{
    // Scratch result
    bool result = false;   
    string signature;
    
    // Private and Public keys
    ECDSA<ECP, SHA256>::PrivateKey privateKey;
    ECDSA<ECP, SHA256>::PublicKey publicKey;
    /////////////////////////////////////////////
    // Load key in PKCS#9 and X.509 format     
    LoadPrivateKey( "ec.private.key", privateKey );
    LoadPublicKey( "ec.public.key", publicKey );
    /////////////////////////////////////////////
    // Sign and Verify a message   
    string message ;
    loadFile2base64("hello.png", message);
    result = SignMessage( privateKey, message, signature );
    assert( true == result );

    string image;
    StringSource (message,true,new Base64Decoder(new StringSink(image)));
    
    StringSource (image+signature,true , new FileSink( "md5.png", true /*binary*/ ));

    return 0;
}

void loadFile2base64(const std::string& filename, string& mess) {
    
    FileSource file(filename.c_str(), true, new Base64Encoder(new StringSink(mess)));
    file.PumpAll();
    
}

bool SignMessage( const ECDSA<ECP, SHA1>::PrivateKey& key, const string& message, string& signature )
{
    AutoSeededRandomPool prng;
    
    signature.erase();    

    StringSource( message, true,
        new SignerFilter( prng,
            ECDSA<ECP,SHA1>::Signer(key),
            new StringSink( signature )
        ) // SignerFilter
    ); // StringSource
    
    return !signature.empty();
}

bool VerifyMessage( const ECDSA<ECP, SHA1>::PublicKey& key, const string& message, const string& signature )
{
    bool result = false;

    StringSource( signature+message, true,
        new SignatureVerificationFilter(
            ECDSA<ECP,SHA1>::Verifier(key),
            new ArraySink( (byte*)&result, sizeof(result) )
        ) // SignatureVerificationFilter
    );

    return result;
}

我尝试将md5.png原始文件hello.png加载到base 64,以检查两个文件之间的差异:

hello.png:[这里有很多东西]=
md5.png:[这里有很多东西]ATeFuHi2CQaZXGpXM s2L2M7UMaAoAdsID8O301sI8hDWJbR2IsQ5DjM4=

因为md5.png是用hello.png+signature创建的,所以我认为[a lot thing here]后面的字符串是signature的base64,但它不是。
无论如何,从md5.png获取签名或任何方法来验证md5.png文件。

1cosmwyk

1cosmwyk1#

PNG格式由一个标头和若干块组成。每个块具有类型标记、大小和数据。您的签名可以在IEND块后面找到。
因此,您可以从头到尾读取文件,跳过文件头,然后读取刚好足够的块,以知道要跳过多少字节。
或者,您可以从文件的末尾向后查找,直到看到IEND标记(字节序列00 00 00 00 73 69 78 68 ?? ?? ?? ??),您的签名也有可能恰好包含这样的字节序列。

相关问题