从文件检索私钥/公钥 (OpenSSL) 时出现随机字符

发布于 2024-11-06 02:51:37 字数 2513 浏览 0 评论 0原文

我正在尝试制作一个程序,在使用 OppenSSL EC 函数 EC_KEY_generate_key 生成公钥/私钥对后,将它们存储在单独的文件中并检索它们以生成 ECDH 密钥。

我的问题是,虽然我正确存储它们(没有任何附加字符),但当我读取文件并尝试将十六进制字符转换为 BIGNUM 时,字符“04”或“00”随机出现(甚至有时不出现)。因此,当我尝试设置公钥/私钥并检查整个密钥时,它失败了。有人可以帮我解决这个问题吗?密钥检查失败是这些字符造成的还是正常现象?

这是我生成/存储私钥的代码(公钥是相同的):

    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

这是我用于检索私钥的代码:

    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);

任何建议将不胜感激!!!!谢谢!!!

在阅读完回复帖子后,我尝试使用这些方法来解码和编码公钥,但是当我尝试计算 ECDH 密钥时,我遇到了分段错误。我的程序的目标是生成两个 EC 密钥,将它们写入多个文件,然后检索它们并用它们计算 ECDH 密钥。这是我在第一个线程中对原始程序进行的更改的列表,如果有问题请告诉我:

* 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)

我已经厌倦了这个 OpenSSL 库...对于首次使用的用户来说它是如此难以访问...

I am trying to make a program that after it generates a public/private key pair using OppenSSL EC function EC_KEY_generate_key store them in separate files and retrieve them to generate an ECDH KEY.

My problem is that although I store them correctly(without any additional character), when I read the file and try to convert the hex characters to BIGNUM a character '04' or '00' randomly appears (or even sometimes not). So when I try to set the public/private keys and check the whole key, it fails. Could anyone help me with this issue? Could the key checking failure be caused by these characters or they are normal?

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

    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 for retrieving 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 advise would be very appreciated!!!!Thanks!!!

After I read the answering post, I have tried to use these methods to decode and encode the public key, but by the time I try to compute the ECDH key I get a segmentation fault. The target of my program is to generate two EC keys, write them into several files and then, retrieve them and compute an ECDH key with them. This is the list of the things I change from my original program in the first thread, please tell me if 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 quite fed up with this OpenSSL library...it is so inaccessible for first-time users...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

徒留西风 2024-11-13 02:51:37

EC 公钥不是一个整数;它是一个曲线点,可以被认为是一对整数。这两个整数是点坐标(通常称为 XY)。

一些符号:曲线是在有限域中定义的。有限域元素可以映射到从 0q-1 的整数,其中 q 是域大小(在曲线的情况下)如果您使用,q 是一个略小于 2192 的素数)。令nq-1字节大小:这是q-1的无符号大端表示形式的大小,即满足28(n-1) <= q-1 <<的整数28n。对于您的曲线,n = 24

使用这些符号,曲线点的标准表示恰好由 1+2n 个字节组成,按顺序依次为:

  • 值 0x04 的字节
  • x 的无符号大端表示em> 超过 n 字节
  • y 超过 n 字节的无符号大端表示

因此这解释了您的“0x04”额外字节;此外,由于 xy 将在恰好 n 个字节上进行编码,这可能会强制包含额外的“0x00”字节,以防它们实际值小于 28(n-1) (根据你的曲线,平均而言,大约 1/128 的公共数据应该是这种情况键)。

这种表示形式还有其他变体(压缩,其中总大小为 1+n,第一个字节为 0x02 或 0x03,以及混合 >,大小为 1+2n,其中第一个字节是 0x06 或 0x07),但它们在 ECDSA 标准 (X9.62-2005) 和谣言中被认为是可选的据说压缩格式已获得专利。

底线:如果您想对 EC 公钥进行编码和解码,您应该查看 o2i_ECPublicKey()i2o_ECPublicKey(),并将它们作为任意字节序列进行处理,不是编码的整数。

An EC public key is not an integer; it is a curve point which can be thought as a pair of integers. Those two integers are the point coordinates (often called X and Y).

Some notations: the curve is defined in a finite field. The finite field elements can be mapped to integers from 0 to q-1, where q is the field size (in the case of the curve you use, q is a prime integer slightly lower than 2192). Let n be the size in bytes of q-1: this is the size of the unsigned big endian representation of q-1, namely the integer such that 28(n-1) <= q-1 < 28n. For your curve, n = 24.

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

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

So this explains your '0x04' extra byte; also, since x and y are to be encoded over exactly n bytes, this may force the inclusion extra '0x00' bytes, in case their actual value turns out to be smaller than 28(n-1) (with your curve, this should be the case, on average, for about 1/128th of public keys).

There are other variants of this representation (compressed, in which the total size is 1+n and the first byte is 0x02 or 0x03, and hybrid, of size 1+2n, where the first byte is 0x06 or 0x07), but they are considered as optional in the ECDSA standard (X9.62-2005) and rumor has it that 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 handle them as sequence of arbitrary bytes, not encoded integers.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文