Search code examples
opensslecdsa

How can I get it pubkey with Openssl:ECDSA


I want to use the basic func of ecdsa:keygen\sign\verify. After reading the doc openssl/ecdsa

I write this:

#include <openssl/ecdsa.h>
#include <openssl/sha.h>
#include <openssl/obj_mac.h> // for NID_secp192k1\  
#include <stdio.h>
int main(int argc, char **argv){
  int ret;
  ECDSA_SIG *sig;
  EC_KEY *eckey;
  eckey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
  EC_KEY_generate_key(eckey);
  sig = ECDSA_SIG_new();
  if (eckey == NULL)
    printf("err1");
  unsigned char dgst[] = "test";
  unsigned char res[32];
  SHA256(dgst, 32, res);
  for (int i = 0; i < 32; i++)
  {
    printf("%02x", res[i]);
  }
  sig = ECDSA_do_sign(res, 32, eckey);
  if (sig == NULL)
    printf("err\n");
  printf("\n");
  ret = ECDSA_do_verify(res, 32, sig, eckey);
  printf("%d\n", ret);
}

This code worked. However, in ECDSA_do_Verify the input is eckey, including a public key and private key. But I just want to use pubkey to verify. So how can I achieve this goal?

Any help will be appreciated.


Solution

  • #include <openssl/x509.h>
    ...
    unsigned char *ptr = NULL;
    int n = i2d_EC_PUBKEY (eckey, &ptr); // 'export' a representation of the publickey 
    const unsigned char *copy = ptr;
    EC_KEY * ecpub = d2i_EC_PUBKEY (NULL, &copy, n); // 'import' it to a new object
    OPENSSL_free (ptr); // for real code, not needed for a test hack like yours
    

    Of course in a real application you would need to store the keypair someplace, and probably get a certificate for the publickey, which the former probably and the latter definitely already provide an externalized publickey to be read back in.

    PS: I forgot to say, but you are using as input to SHA256() a purported 32-byte buffer dgst, but dgst is only 5 bytes, so this is technically undefined behavior (and can do anything) and in practice will probably use whatever random garbage happens to be in memory following dgst, which makes your results unreproducible and unverifiable.