Random characters when retrieving a secret / public key (OpenSSL) from a file

I am trying to create a program that, after creating a public / private key pair using the OppenSSL EC function EC_KEY_generate_key, stores them in separate files and extracts them to generate an ECDH key.

My problem is that although I store them correctly (without any extra character), when I read the file and try to convert the hexadecimal characters to BIGNUM, the character β€œ04” or β€œ00” appears accidentally (or even sometimes not), Therefore, when I try to set public / private keys and verify the entire key, it fails. Can someone help me on this? Can key verification errors be caused by these characters, or are they normal?

Here is my code that generates / stores the private key (the same public):

EC_KEY *b = NULL; const BIGNUM *ppriv_b; FILE *claveprivb; const EC_GROUP *group; b = EC_KEY_new_by_curve_name(NID_X9_62_prime192v1); group = EC_KEY_get0_group(b); EC_KEY_generate_key(b); claveprivb = fopen("/tmp/mnt/claveprivb", "w+"); ppriv_b = EC_KEY_get0_private_key(b); if ((ppriv_b != NULL)) BN_print_fp(claveprivb,ppriv_b); fclose(claveprivb); //Afterwards do the same with the public key 

And here is my code to retrieve the private key:

  int i, s, blen, bout, ret = 0; unsigned char *bbuf; FILE *clavepriv, *clavetotalb; const char cpriv_string[PRIVATE_KEY_SIZE]; BIGNUM *priv; EC_KEY *b = NULL; const EC_GROUP *groupb; b = EC_KEY_new_by_curve_name(NID_X9_62_prime192v1); groupb = EC_KEY_get0_group(b); //Open the file with the hexadecimals (PRIVATE KEY) clavepriv = fopen("/tmp/mnt/claveprivb", "r"); kk2 = fread(&cpriv_string, sizeof(char), PRIVATE_KEY_SIZE, clavepriv); priv = BN_new(); //THIS FUNCTION (HEX2BN) GENERATES THE RANDOM CHARACTER: kk2 = BN_hex2bn(&priv, cpriv_string); ret = EC_KEY_set_private_key(b, priv); //HERE I retrieve the public key by the same way and set it into EC_KEY b, //the same random character appears in the public key if (!EC_KEY_check_key(b)) { printf("EC_KEY_check_key failed\n"); } else { printf("Key verified OK\n"); } //It fails when try to check it. int k; clavetotalb = fopen("/tmp/mnt/clavetotalb", "w+"); k = EC_KEY_print_fp(clavetotalb, b, 0); bout = ECDH_compute_key(bbuf, blen, EC_KEY_get0_public_key(b), b, KDF1_SHA1); 

Any advice would be greatly appreciated !!!! Thanks!!!

After I read the response post, I tried to use these methods to decode and encode the public key, but by the time I try to calculate the ECDH key, I get a segmentation error. The goal of my program is to generate two EC keys, write them to several files, and then extract them and calculate the ECDH key with them. This is a list of things that I am transferring from my original program to the first thread, please tell me something is wrong:

 * Generate EC key (public & private) * Decode the private key with i2d_ECPrivatekey() * Decode the public key with i2o_ECPublickey() * Write them into several files. * Read the file with the public key. * Encode it with o2i_ECPublickey() * Read the file with the private key. * Encode it with d2i_ECPrivatekey(). * Compute the ECDH key.(Here is where I get the segmentation fault) 

I am very tired of this OpenSSL library ... it is not available to first users ...

+4
source share
1 answer

The EC public key is not an integer; this is a point on the curve that can be thought of as a pair of integers. These two integers are point coordinates (often called X and Y).

Some notation: a curve is defined in a finite field. The elements of the final field can be mapped to integers from 0 to q-1, where q is the size of the field (in the case of the used curve q is a prime integer slightly less than 2 192 ), Let n be the size in bytes q-1: this is the size of the unsigned representation of a large number q-1, namely an integer such that 2 8 (n-1) <= q -1 <2 8l . For your curve, n = 24.

With these notations, the standard representation of a curve point is exactly 1 + 2n bytes, which are in this order:

  • value byte 0x04
  • unsigned big endian representation of x over n bytes
  • unsigned big endian representation of y over n bytes

So this explains the extra byte "0x04"; also, since x and y must be encoded in exactly n bytes, this may force the inclusion of additional bytes β€œ0x00” if their actual value is less than 2 8 (n-1) (with your curve, on average it should be about 1 / 128th public keys).

There are other options for this representation (compressed, in which the total size is 1 + n and the first byte is 0x02 or 0x03, and the hybrid is 1 + 2n in size, where the first byte is 0x06 or 0x07) but they are considered optional in the ECDSA standard ( X9.62-2005), and, according to rumors, the compressed format is patented.

Bottom line: if you want to encode and decode EC public keys, you should look at o2i_ECPublicKey() and i2o_ECPublicKey() and treat them as a sequence of arbitrary bytes, not encoded integers.

+5
source

All Articles