我的老师给了我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文件。
1条答案
按热度按时间1cosmwyk1#
PNG格式由一个标头和若干块组成。每个块具有类型标记、大小和数据。您的签名可以在IEND块后面找到。
因此,您可以从头到尾读取文件,跳过文件头,然后读取刚好足够的块,以知道要跳过多少字节。
或者,您可以从文件的末尾向后查找,直到看到IEND标记(字节序列
00 00 00 00 73 69 78 68 ?? ?? ?? ??
),您的签名也有可能恰好包含这样的字节序列。