Я хочу создать подпись для файла, используя OpenSSL.
Я считаю, что мой результат должен соответствовать testfile.sig, сгенерированному openssl следующим образом:
$ openssl dgst -sha1 -binary < testfile > testfile.sha1
$ openssl rsautl -sign -in testfile.sha1 -inkey rsa_private.pem -keyform PEM -out testfile.sig
$ openssl rsautl -verify -inkey rsa_public.pem -pubin -in testfile.sig -hexdump
Loading 'screen' into random state - done
0000 - 9f 23 88 15 2b af d6 a6-9f 4f 1f 7e ee b0 90 dd .#..+....O.~....
0010 - 69 99 2b 3d i.+=
Итак, я использовал код от caf, который был размещен здесь:
Как прочитать файл ключа для использования с HMAC_Init_ex ()
и просто добавил небольшой фрагмент, чтобы сохранить данные после EVP_SignFinal () в файл, так что я
можно просто проверить это с помощью openssl и открытого ключа:
FILE * fp = fopen("out.sig", "wb");
if (fp) {
printf("Writing the signature in a file. # of bytes: %u.\n", sig_len);
fwrite(sig, 1, sig_len, fp);
fclose(fp);
}
И, к моему удивлению, я получил это:
$ openssl rsautl -verify -inkey rsa_public.pem -pubin -in out.sig -hexdump
Loading 'screen' into random state - done
0000 - 30 21 30 09 06 05 2b 0e-03 02 1a 05 00 04 14 9f 0!0...+.........
0010 - 23 88 15 2b af d6 a6 9f-4f 1f 7e ee b0 90 dd 69 #..+....O.~....i
0020 - 99 2b 3d .+=
Теперь, если вы посмотрите результат проверки out.sig, вы увидите, что последние 20
байты соответствуют выходным данным проверки testfile.sig. И эти 20 байтов
действительно, хэш SHA-1 моего файла. Но каковы первые 15 байтов в начале?
Разве EVP_SignInit () / EVP_SignUpdate () / EVP_SignFinal () не должен содержать только хэш
сообщение, или я упускаю что-то очевидное?
Если вам нужна дополнительная информация, пожалуйста, дайте мне знать.
Спасибо
Полная функция, которая использовалась для подписи файла:
int do_evp_sign(FILE * rsa_pkey_file, FILE * in_file)
{
OpenSSL_add_all_digests();
ERR_load_crypto_strings();
EVP_PKEY * pkey = PEM_read_PrivateKey(rsa_pkey_file, NULL, NULL, NULL);
if (pkey == NULL) {
ERR_print_errors_fp(stderr);
return 1;
}
fseek(in_file, 0, SEEK_END);
const size_t lSize = ftell(in_file);
rewind(in_file);
EVP_MD_CTX md_ctx;
EVP_SignInit(&md_ctx, EVP_sha1());
size_t len;
unsigned char buffer[4096];
size_t bytesLeft = lSize;
while (bytesLeft > 0) {
const size_t count = (bytesLeft > sizeof(buffer) ? sizeof(buffer) : bytesLeft);
len = fread(buffer, 1, count, in_file);
if (len != count) {
fprintf(stderr, "Read error! len (%u) != count (%u).\n", len, count);
EVP_PKEY_free(pkey);
return 1;
}
if (!EVP_SignUpdate(&md_ctx, buffer, len))
{
ERR_print_errors_fp(stderr);
EVP_PKEY_free(pkey);
return 1;
}
bytesLeft -= len;
}
unsigned int sig_len;
unsigned char * sig = (unsigned char *)malloc(EVP_PKEY_size(pkey));
if (!sig) {
fprintf(stderr, "Couldn't allocate %u bytes of memory.\n", EVP_PKEY_size(pkey));
EVP_PKEY_free(pkey);
return 1;
}
if (!EVP_SignFinal(&md_ctx, sig, &sig_len, pkey))
{
ERR_print_errors_fp(stderr);
EVP_PKEY_free(pkey);
free(sig);
return 1;
}
FILE * fTemp = fopen("out.sig", "wb");
if (fTemp) {
printf("Writing the signature to a file. Number of bytes: %u.\n", sig_len);
fwrite(sig, 1, sig_len, fTemp);
fclose(fTemp);
}
printf("Signature: \n");
for (unsigned int i = 0; i != sig_len; ++i)
{
printf("%02x", sig[i]);
if (i % 16 == 15)
printf("\n");
}
printf("\n");
EVP_PKEY_free(pkey);
free(sig);
return 0;
}