I am trying to create private and public keys for DNSSEC algorithm 13:
#include <stdio.h>
#include <stdlib.h>
#include <openssl/ec.h>
#include <openssl/obj_mac.h>
#include <openssl/bn.h>
int main()
{
EC_KEY *eckey = NULL;
const EC_POINT *pub_key = NULL;
const EC_GROUP *group = NULL;
const BIGNUM *res;
BN_CTX *ctx;
ctx = BN_CTX_new();
eckey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
EC_KEY_generate_key(eckey);
res = EC_KEY_get0_private_key(eckey);
printf("Private: %s\n", BN_bn2hex(res));
group = EC_KEY_get0_group(eckey);
pub_key = EC_KEY_get0_public_key(eckey);
printf("Public: %s\n", EC_POINT_point2hex(group, pub_key, 4, ctx));
return 0;
}
Testing:
$ gcc -lcrypto test.c
$ ./a.out | perl -MMIME::Base64 -pe 's/(?<=:\s)(.+)/encode_base64(pack "H*", $1)/e'
Private: PgO6atAv+YEuyvRvvuTyDf8kz7vp/hQKNdKJyvVVBoQ=
Public: BAPe3AhjpcMCQPpZzZeFRwVuR4su/cmd3Vl2zn+i2izEWxOdbww/3fw4yAi0yQUUhlvXZqTnaeol
OK03LOdsKkk=
(Perl line just converts hex notation to binary and then to base64.)
But if I set this private key to DNS server (which accepts only private key and generates public on the fly) it returns public key which doesn't match this one returned by OpenSSL
Key inside DNS server (PowerDNS):
Private-key-format: v1.2
Algorithm: 13 (ECDSAP256SHA256)
PrivateKey: PgO6atAv+YEuyvRvvuTyDf8kz7vp/hQKNdKJyvVVBoQ=
$ dig @127.0.0.1 +short example.com DNSKEY
257 3 13 A97cCGOlwwJA+lnNl4VHBW5Hiy79yZ3dWXbOf6LaLMRbE51vDD/d/DjI CLTJBRSGW9dmpOdp6iU4rTcs52wqSQ==
So, I got A97cCGOlwwJA+lnNl4VHBW5Hiy79yZ3dWXbOf6LaLMRbE51vDD/d/DjI CLTJBRSGW9dmpOdp6iU4rTcs52wqSQ==
which doesn't match BAPe3AhjpcMCQPpZzZeFRwVuR4su/cmd3Vl2zn+i2izEWxOdbww/3fw4yAi0yQUUhlvXZqTnaeol
OK03LOdsKkk=
.
Why this happened?