Problème: En utilisant le code de démonstration écrit (donné ci-dessous), je peux créer et vérifier sans problèmes. Cependant, en utilisant l'outil de ligne de commande openssl, la vérification d'une signature (créée par le code de démonstration) semble toujours échouer.Créer et vérifier la signature dans le code et à partir de la ligne de commande en utilisant ECDSA
Qu'est-ce que je l'ai fait: Le code de démonstration crée une clé publique/privée définie paire, signe alors un hachage défini et vérifie.
C'est la sortie du programme:
Public key: 04DFEC134530603832A31F8885EF01888884483D611F87A698213F168534EC06D85D21F7C85795435BC9A7F78190126CC6E52E050CBDFD43E27175FB1DF3E3DEF6
Hash: 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
Verified EC Signature
R: 383EB65E4A284CBCBA41A9777CE7C0816C5C23161EA9BC4EF8B1E668C7641A2A
S: 608F4BAB9DFE6DC8F976C32D72508CD5BD68F9E325ADED69A9883CE487E6698B
comme sorties bien les fichiers follwing:
privkey.pem
(clé privée au format PEM)pubkey.pem
(clé publique au format PEM)data.bin
(le hachage, rien d'extraordinaire)data_sig.der
(la signature codée DER: R & valeur S)
Tous les fichiers semblent être créés correctement.
Ensuite, j'essaie de vérifier data_sig.der
avec l'outil de ligne de commande openssl.
$ openssl dgst -verify pubkey.pem -signature data_sig.der data.bin
Verification Failure
Pourquoi cela échoue-t-il?
Je ne peux que supposer que l'un des 4 fichiers a été écrit de manière incorrecte, mais je tout revérifié et ne peut pas repérer mon erreur.
De plus, en utilisant les fichiers PEM créés par le programme de démonstration, signe & vérifier belles œuvres de la ligne de commande:
$openssl dgst -sign privkey.pem data.bin > data_sig2.der
$openssl dgst -verify pubkey.pem -signature data_sig2.der data.bin
Verified OK
Voici le code de démonstration (compile avec gcc demo_code.c -lcrypto -lssl -o demo_code
):
#include <stdio.h>
#include <stdlib.h>
#include <openssl/ec.h>
#include <openssl/ecdsa.h>
#include <openssl/obj_mac.h>
#include <openssl/bio.h>
#include <openssl/x509.h>
#include <openssl/ecdsa.h>
#include <openssl/pem.h>
#include <openssl/bn.h>
void createSignature()
{
EC_KEY* eckey = EC_KEY_new();
EC_GROUP* ecgroup = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
EC_KEY_set_group(eckey,ecgroup);
EC_KEY_set_asn1_flag(eckey, OPENSSL_EC_NAMED_CURVE);
/* the private key value */
const char *p_str = "7D22AB6A1FD3FC1F5EBEDCA222151375683B733E9DDC9CA5B2485E202C55D25C";
BIGNUM* prv = BN_new();
BN_hex2bn(&prv, p_str);
EC_POINT* pub = EC_POINT_new(ecgroup);
/* calculate the public key */
EC_POINT_mul(ecgroup, pub, prv, NULL, NULL, NULL);
/* add the private & public key to the EC_KEY structure */
EC_KEY_set_private_key(eckey, prv);
EC_KEY_set_public_key(eckey, pub);
/* output public key in hex format */
char* hexPKey = EC_POINT_point2hex(ecgroup, pub, POINT_CONVERSION_UNCOMPRESSED, NULL);
printf("Public key: %s \n", hexPKey);
/* create hash */
printf("Hash: ");
uint8_t hash[32];
for(int i=0; i < 32; i++) {
hash[i] = i;
printf("%02x",hash[i]);
}
printf("\n");
/* create and verify signature */
ECDSA_SIG* signature = ECDSA_do_sign(hash, 32, eckey);
//hash[0] = 0xff; // Uncomment to test if verification fails with a wrong hash
if (1 != ECDSA_do_verify(hash, 32, signature, eckey)) {
printf("Failed to verify EC Signature\n");
} else {
printf("Verified EC Signature\n");
}
/*print R & S value in hex format */
char* hexR = BN_bn2hex(signature->r);
char* hexS = BN_bn2hex(signature->s);
printf("R: %s \nS: %s\n", hexR, hexS);
/* export raw signature to DER-encoded format */
int sigSize = i2d_ECDSA_SIG(signature, NULL);
uint8_t* derSig = (uint8_t*)malloc(sigSize);
uint8_t* p = derSig; //memset(sig_bytes, 6, sig_size);
sigSize= i2d_ECDSA_SIG(signature, &p);
EVP_PKEY* pkey = EVP_PKEY_new();
EVP_PKEY_set1_EC_KEY(pkey, eckey);
/* write files */
FILE* fp = fopen("pubkey.pem", "w");
PEM_write_PUBKEY(fp, pkey);
fclose(fp);
fp = fopen("privkey.pem", "w");
PEM_write_PrivateKey(fp, pkey, NULL, NULL, 0, 0, NULL);
fclose(fp);
fp = fopen("data.bin", "w");
fwrite(hash, 1, sizeof(hash), fp);
fclose(fp);
fp = fopen("data_sig.der", "w");
fwrite(derSig, 1, sigSize, fp);
fclose(fp);
/* free runtime allocated res */
free(derSig);
OPENSSL_free(hexPKey); OPENSSL_free(hexR); OPENSSL_free(hexS);
BN_free(prv);
EC_POINT_free(pub);
EC_GROUP_free(ecgroup);
EC_KEY_free(eckey);
}
int main(int argc, char** argv) {
createSignature();
return (EXIT_SUCCESS);
}
Vous avez raison! - Merci beaucoup – 0laf