我有一个原始 ECDSA 签名:R 和 S 值。我需要 DER 编码版本的签名。有没有一种直接的方法可以使用 c 接口在 openssl 中执行此操作?
我目前的尝试是使用i2d_ECDSA_SIG(const ECDSA_SIG *sig, unsigned char **pp)
填充一个ECDSA_SIG*
。该调用返回非零,但目标缓冲区似乎没有更改。
我最初填写我的 ECDSA SIGr
and s
价值观。我没有看到任何错误。手册页说当我调用时应该分配 r 和 sECDSA_SIG_new
ECDSA_SIG* ec_sig = ECDSA_SIG_new();
if (NULL == BN_bin2bn(sig, 32, (ec_sig->r))) {
dumpOpenSslErrors();
}
DBG("post r :%s\n", BN_bn2hex(ec_sig->r));
if (NULL == BN_bin2bn(sig + 32, 32, (ec_sig->s))) {
dumpOpenSslErrors();
}
DBG("post s :%s\n", BN_bn2hex(ec_sig->s));
S 和 R 现在已设置:
post r :397116930C282D1FCB71166A2D06728120CF2EE5CF6CCD4E2D822E8E0AE24A30
post s :9E997D4718A7603942834FBDD22A4B856FC4083704EDE62033CF1A77CB9822A9
现在制作编码签名。
int sig_size = i2d_ECDSA_SIG(ec_sig, NULL);
if (sig_size > 255) {
DBG("signature is too large wants %d\n", sig_size);
}
DBG("post i2d:%s\n", BN_bn2hex(ec_sig->s));
s 没有改变:
post i2d:9E997D4718A7603942834FBDD22A4B856FC4083704EDE62033CF1A77CB9822A9
此时,我已准备好足够的字节,并将目标设置为全部 6,以便很容易看到发生了什么变化。
unsigned char* sig_bytes = new unsigned char[256];
memset(sig_bytes, 6, 256);
sig_size = i2d_ECDSA_SIG(ec_sig, (&sig_bytes));
DBG("New size %d\n", sig_size);
DBG("post i2d:%s\n", BN_bn2hex(ec_sig->s));
hexDump("Sig ", (const byte*)sig_bytes, sig_size);
新尺码是71New size 71
和 s iis 仍然相同:
`post i2d:9E997D4718A7603942834FBDD22A4B856FC4083704EDE62033CF1A77CB9822A9`
十六进制转储全是 6。
--Sig --
0x06: 0x06: 0x06: 0x06: 0x06: 0x06: 0x06: 0x06:
0x06: ...
即使调用没有返回 0,转储仍然全是 6。在对这个原始签名进行 DER 编码时,我缺少什么?