英文:
Why two rsa signatures are different from each other when one is generated by command and the other is generated by command?
问题
The code you provided seems to be generating a signature using the OpenSSL library, but you're encountering an issue where the generated signature differs from the one generated using a command line tool, specifically with missing zeros in the code-generated signature.
The most likely reason for this issue is how the code is handling binary data. In C++, when you read binary data from a file, it may treat null characters (zeros) as string terminators. To ensure that null characters are not treated this way and that all binary data is correctly processed, you should open the file in binary mode. In your code, you should change the line that opens the input file from this:
std::ifstream input_file("data.txt", std::ios::binary);
to:
std::ifstream input_file("data.txt", std::ios::binary | std::ios::ate);
The std::ios::ate
flag ensures that the file is opened in binary mode and that the file position is set to the end of the file, which can help when reading binary data with null characters.
Once you've made this change, rebuild and run your code to see if the generated signature now matches the one generated using the command line tool. This should resolve the issue with missing zeros in the signature.
英文:
I use the code below to generate a signature,then I use command line to verify it,and it verify failure.
#include <iostream>
#include <fstream>
#include <vector>
#include <openssl/evp.h>
#include <openssl/pem.h>
int main() {
FILE* pkey_file = fopen("private_key.pem", "r");
if (!pkey_file) {
std::cerr << "Error opening private key file\n";
return 1;
}
EVP_PKEY* pkey = PEM_read_PrivateKey(pkey_file, nullptr, nullptr, nullptr);
fclose(pkey_file);
if (!pkey) {
std::cerr << "Error reading private key\n";
return 1;
}
std::ifstream input_file("data.txt", std::ios::binary);
std::vector<char> buffer(std::istreambuf_iterator<char>(input_file), {});
EVP_MD_CTX* ctx = EVP_MD_CTX_new();
if (EVP_SignInit_ex(ctx, EVP_sha256(), nullptr) != 1) {
std::cerr << "Error initializing signing context\n";
EVP_PKEY_free(pkey);
return 1;
}
if (EVP_SignUpdate(ctx, buffer.data(), buffer.size()) != 1) {
std::cerr << "Error updating signing context\n";
EVP_PKEY_free(pkey);
return 1;
}
unsigned int len = EVP_PKEY_size(pkey);
std::vector<unsigned char> signature(len);
if (EVP_SignFinal(ctx, signature.data(), &len, pkey) != 1) {
std::cerr << "Error finalizing signature\n";
EVP_PKEY_free(pkey);
return 1;
}
signature.resize(len); // Resize signature to actual size
for (unsigned char c : signature) {
std::cout << std::hex << static_cast<int>(c);
}
std::cout << '\n';
EVP_PKEY_free(pkey);
EVP_MD_CTX_free(ctx);
return 0;
}
The private key is below.
-----BEGIN RSA PRIVATE KEY-----
MIIEoQIBAAKCAQEAujWddIWHz7uYYqnV/aOLVYTYlXCgvozEn94WAPY7qAgD7CJH
lizWONX/snwVjqiPD+DITEPjXa5MGf3WSFJGYk9yxd8bzr9JJFWt2P3Sg8RoaegJ
9K5zrwQ1sdmBF7gBTN44TsEGYvNXoQ+faK+a5kjzRy5LNwEeAWb06dNAEsQsVvY8
LgxHoKIrLmaSTaDE0TW9bHiJ7xhAr2plPE86yHGVqt9ZR+J2OrGdkM0jAfrg9Zzb
niZkilUcaE1YqsVFfXff7Y0FPt2PoCd+bzncZjbyvR0mdLN5K5aVDHZYBheHR6xA
qQjkRQ8mrHLTotSEeJpTfjev0byEIRSLDD6SmwIDAQABAoH/LJlgFMfyz0aHdX3V
LaAWXFexm+kQ6iSEpRmOgbTGw+l0lEOnp5Ojl0Wcm71Y+aoxhVsbtC9XSwgxqVXP
BV2nET7CEtFdOppkXGGlsC8I+BaoTnX6Y8huqZM8m2bth32XvDv0o4JEHX40QaoQ
Q0CL5UzhecFMu1+EmSj5y49GNimyiInVv94sw3v6+dhNi8SRDhePSoAK4bklT8aM
k18qYQHOsv8cV4N4WssWyguU7wmuVsPztJtkx+MVh1DXVtRQ5QCW3X0/dpYIcp5x
LBGXSw4+sML0m4vZY/ogJcVh2f0xTLbZcxQFfDt1AJPGx0J8C4LfeRoDkmL7BsmO
AmPhAoGBAMVenorDu0L6zKZSnM3QIMK+kG82y7tqxCVFMc1buvKWnEad4BLpMYtK
hWlsP6DyTJ8Pql79997k76LCVhQ9t66DMgRzfrUcQL98qO9LFECWxCUa7+7E3mS6
kRFtzv+XbsWr4YHFRYQQnxvrdD1m6QO2kicv/hr4T6AjxTM6SysjAoGBAPGGTBr+
KqlvSxWxtQh6/N2OdG4+z0po9Isir45Oi+dfcgC9k7y0llx5pvO5ZbrwIGvvqQbX
Cxf6klolMgXJWGIpaEe4kGPnWf8B9T2FZ32Q8TjIiehlErLUhW2rc11brpg9pLtf
i6ApVCQLdiaIm7fuF24zPGm3EPLUWvstsE4pAoGBALCNuKMG/j+nXGQ4KF6PnI64
qzlhOhQ4KKfyYt+B/BS/l6Iv3d7szU395qPsmmqd9N6gw9Xft9ii0J622wuWPfaV
E6wZqLHYSS9CE1ijv8UbWPCcTR846nwOzHBb2zyWORgIblyInGvL9piiIkQ/B5gz
vD/j1ZpIn+nvtZrivZUjAoGAcL+i048HV2VvBceZnUXcuYkA7V5A4pmwXytoDOS6
Bt7Vl2boitU6xBy+RVStGuFyITEWFO1abm042QA4I99kdR6jYafVL+4WYycE1x1p
vIJnOXzUdDqKyhTP3OyGxHRCQyuztQzbX38rmlAHbeGj3+8z3OvqLeeZ7+IWPt+L
SFECgYAwuWwv8akZ2hmeYu/ehYhj7UwigLv+uS0XkKlpXsiLjj99gHAj8rGZn5Op
XnJ+ABDKRnZzOjUbERxXaWW8Xsls7N5p30PgGcOKcCCxU84pw0Vxqy56xgF2Mab5
X1zgQAZ7fnIrkCJzrBERkgr5Wet1y7XAjzYYBEHXbM9nBQ6Pjg==
-----END RSA PRIVATE KEY-----
The content of file I sign is:
111111
And my public key is:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAujWddIWHz7uYYqnV/aOL
VYTYlXCgvozEn94WAPY7qAgD7CJHlizWONX/snwVjqiPD+DITEPjXa5MGf3WSFJG
Yk9yxd8bzr9JJFWt2P3Sg8RoaegJ9K5zrwQ1sdmBF7gBTN44TsEGYvNXoQ+faK+a
5kjzRy5LNwEeAWb06dNAEsQsVvY8LgxHoKIrLmaSTaDE0TW9bHiJ7xhAr2plPE86
yHGVqt9ZR+J2OrGdkM0jAfrg9ZzbniZkilUcaE1YqsVFfXff7Y0FPt2PoCd+bznc
ZjbyvR0mdLN5K5aVDHZYBheHR6xAqQjkRQ8mrHLTotSEeJpTfjev0byEIRSLDD6S
mwIDAQAB
-----END PUBLIC KEY-----
The hex of signature generated by this code is:
9751cc93bbd0486efe89abe4872d52f6d71886815af1c2f3d13f92e3a4c636de86bdcfb9512ec4538a48f4798965f6c91845e7efc7a8bf20182bbd8d5d9632123dc79caa329ffa33eb2b333eaff64ea137e83e3deac3bcac6c177056deab198cfd548799c6adad3cde3359ba461185c82b2c25c574c31f473e95c8586826cf5991ae1687fdcb7c0ec2eb83510f494715994c21ffcca1b4af7e45fe7b678c6774c437b9b18af1f3c83f2a284961fc2e0ff9aebf1c9c8e373bcf8adc674c41c5b81f357988b39513d63da564d8d349d964d8dde879f66578f8fb2847c4e1c45ed287bca8b6344a6785b384f3d9b153e5ef5626db99056
And I generate a signature using commnad line,the difference I have highlighted below:
9751cc93bbd0486efe89abe48702d52f6d71886815af1c2f3d13f92e3a4c636de86bdcfb9512ec**0**4538a**0**48f4798965f6c91845e7efc7a8b**0**f20182bbd8d5d9632123dc79caa329ffa33**0**eb2b333eaff064ea137**0**e83**0**e3deac3bcac6c177056deab19**0**8cf**0**d548799c6ad**0**a**0**d3cde3359ba461185c82b2c25c574c31f473e95**0**c8586826cf599**0**1ae1687fdcb**0**7c0ec2eb83510f494715994c21ffcca1b4af7e45fe7b678c6774c437b9b18af1f3c83f2a284961fc2**0**e0**0**ff9aebf1c9**0**c8e373bcf8adc674c41**0**c5b81f357988b39513d63da564d8d349d964d**0**8dde879f66578f8fb2847c4e1c45e**0**d287bca8b6344a6785b384f3d9b153e5ef5626db99056
I tried two different system(Centos and Kail) get the same result;
And signature generated by command line can be verified and code can not.So I wonder why signature generated by code miss several 0 and how could I fix it.Any help or idea would be appreciated.
答案1
得分: 2
我将引用我之前提供的另一个答案链接:https://stackoverflow.com/a/64551328/11829247
基本上出错的地方是,当你打印值11时,你得到的是“b”,而不是“0b”。你可以通过在打印时添加 std::setfill('0') << std::setw(sizeof(c) * 2)
来修复这个问题 - 解释在链接的答案中。
英文:
I am going to refer you to another answer I have given: https://stackoverflow.com/a/64551328/11829247
Basically what goes wrong is that when you print the value 11 you get "b", not "0b". You can fix this by adding std::setfill('0') << std::setw(sizeof(c) * 2)
to your print - explanation is in the linked answer.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论