我正在尝试为DNSSEC算法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;
}
测试:
$ 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行只是将十六进制表示法转换为二进制,然后转换为base64。)
但是,如果我将此私钥设置为DNS服务器(仅接受私钥并在运行中生成公共),则返回与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==
所以,我的A97cCGOlwwJA+lnNl4VHBW5Hiy79yZ3dWXbOf6LaLMRbE51vDD/d/DjI CLTJBRSGW9dmpOdp6iU4rTcs52wqSQ==
与BAPe3AhjpcMCQPpZzZeFRwVuR4su/cmd3Vl2zn+i2izEWxOdbww/3fw4yAi0yQUUhlvXZqTnaeol
OK03LOdsKkk=
不匹配。
为什么会这样?
答案 0 :(得分:3)
除了OpenSSL添加0x04
前缀字节外,这两个值实际上是相同的。这是一种标准格式,0x04
表示该点处于未压缩形式,后面是该点的X坐标的32个字节,然后是Y坐标的32个字节,总共65个字节。
DNS条目只有X和Y坐标,没有前缀字节,总共64个字节。
由于这个额外字节是第一个字节,它会改变base 64编码的对齐方式,并且两个编码值看起来完全不同。
比较值,首先是OpenSSL的值:
$ echo BAPe3AhjpcMCQPpZzZeFRwVuR4su/cmd3Vl2zn+i2izEWxOdbww/3fw4yAi0yQUUhlvXZqTnaeolOK03LOdsKkk= | base64 -D | xxd
00000000: 0403 dedc 0863 a5c3 0240 fa59 cd97 8547 .....c...@.Y...G
00000010: 056e 478b 2efd c99d dd59 76ce 7fa2 da2c .nG......Yv....,
00000020: c45b 139d 6f0c 3fdd fc38 c808 b4c9 0514 .[..o.?..8......
00000030: 865b d766 a4e7 69ea 2538 ad37 2ce7 6c2a .[.f..i.%8.7,.l*
00000040: 49
接下来来自DNS的值:
echo A97cCGOlwwJA+lnNl4VHBW5Hiy79yZ3dWXbOf6LaLMRbE51vDD/d/DjICLTJBRSGW9dmpOdp6iU4rTcs52wqSQ== | base64 -D | xxd
00000000: 03de dc08 63a5 c302 40fa 59cd 9785 4705 ....c...@.Y...G.
00000010: 6e47 8b2e fdc9 9ddd 5976 ce7f a2da 2cc4 nG......Yv....,.
00000020: 5b13 9d6f 0c3f ddfc 38c8 08b4 c905 1486 [..o.?..8.......
00000030: 5bd7 66a4 e769 ea25 38ad 372c e76c 2a49 [.f..i.%8.7,.l*I
你可以看到,除了额外的0x04
,两个值是相同的。