d2i_RSA_PUBKEY,d2i_RSAPrivateKey和d2i_RSAPublicKey返回NULL [英] d2i_RSA_PUBKEY, d2i_RSAPrivateKey and d2i_RSAPublicKey returns NULL

查看:3569
本文介绍了d2i_RSA_PUBKEY,d2i_RSAPrivateKey和d2i_RSAPublicKey返回NULL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用下面的命令创建一个RSA私钥:

I created a RSA private key using the following command:

 openssl genrsa -out keypair.pem 2048

我必须使用DER-CN codeD键(PKCS#1)为这个项目,所以我生成了两个DER文件从这个PEM-CN codeD私钥文件 - 一个具有私钥和另一用公钥

I must to use DER-encoded keys (PKCS#1) for this project, so I generated two DER files from this PEM-encoded private key file - one with the private key and another with the public key.

openssl rsa -inform PEM -in keypair.pem -outform DER -pubout -out public.der

openssl rsa -inform PEM -in keypair.pem -outform DER -out private.der

在我的code,我装在焦炭这两个文件*变量的内容。

In my code, I loaded the contents of both these files in char* variables.

如预期以下作品无:

d2i_RSA_PUBKEY(NULL, &public_key_bytes, public_key_length);

d2i_RSAPublicKey(NULL, &public_key_bytes, public_key_length);

d2i_RSAPrivateKey(NULL, &private_key_bytes, private_key_length);

我知道,所有的东阳人返回。我也试过如下:

RSA * rsa = RSA_new();
d2i_RSA_PUBKEY(&rsa, &public_key_bytes, public_key_length);

RSA * rsa = RSA_new();
d2i_RSAPublicKey(&rsa, &public_key_bytes, public_key_length);

RSA * rsa = RSA_new();
d2i_RSAPrivateKey(&rsa, &private_key_bytes, private_key_length);

所有收益以及

我的完整的测试code是如下:

My complete test code is as follows:

#include <stdio.h>
#include <stdlib.h>

#include <openssl/rsa.h>
#include <openssl/bio.h>
#include <openssl/pem.h>

typedef struct
{
    int len;
    char * bytes;
} FileData;

static FileData readFileBytes(const char * name, int zero_ended)
{
    FILE * fl = fopen(name, "r");
    if (fl == NULL) return (FileData) { .len = 0, .bytes = NULL };
    fseek(fl, 0, SEEK_END);
    long len = ftell(fl);
    char * ret = malloc(len + (zero_ended ? 1 : 0));
    fseek(fl, 0, SEEK_SET);
    fread(ret, 1, len, fl);
    if (zero_ended) ret[len] = 0;
    fclose(fl);
    return (FileData) { .len = len, .bytes = ret };
}

int main()
{
    FileData private_key = readFileBytes("../private.der", 0);
    FileData public_key = readFileBytes("../public.der", 0);

    char* public_key_bytes = public_key.bytes;
    int public_key_length = public_key.len;

    char* private_key_bytes = private_key.bytes;
    int private_key_length = private_key.len;

    RSA * rsa;

    public_key_bytes = public_key.bytes;
    public_key_length = public_key.len;
    rsa = d2i_RSA_PUBKEY(NULL, &public_key_bytes, public_key_length);
    printf("d2i_RSA_PUBKEY(NULL, &public_key_bytes, public_key_length) != NULL -> %s\n", (rsa != NULL) ? "true" : "false");

    public_key_bytes = public_key.bytes;
    public_key_length = public_key.len;
    rsa = d2i_RSAPublicKey(NULL, &public_key_bytes, public_key_length);
    printf("d2i_RSAPublicKey(NULL, &public_key_bytes, public_key_length) != NULL -> %s\n", (rsa != NULL) ? "true" : "false");

    private_key_bytes = private_key.bytes;
    private_key_length = private_key.len;
    rsa = d2i_RSAPrivateKey(NULL, &private_key_bytes, private_key_length);
    printf("d2i_RSAPrivateKey(NULL, &private_key_bytes, private_key_length) != NULL -> %s\n", (rsa != NULL) ? "true" : "false");

    public_key_bytes = public_key.bytes;
    public_key_length = public_key.len;
    rsa = RSA_new();
    rsa = d2i_RSA_PUBKEY(&rsa, &public_key_bytes, public_key_length);
    printf("d2i_RSA_PUBKEY(&rsa, &public_key_bytes, public_key_length) != NULL -> %s\n", (rsa != NULL) ? "true" : "false");

    public_key_bytes = public_key.bytes;
    public_key_length = public_key.len;
    rsa = RSA_new();
    rsa = d2i_RSAPublicKey(&rsa, &public_key_bytes, public_key_length);
    printf("d2i_RSAPublicKey(&rsa, &public_key_bytes, public_key_length) != NULL -> %s\n", (rsa != NULL) ? "true" : "false");

    private_key_bytes = private_key.bytes;
    private_key_length = private_key.len;
    rsa = RSA_new();
    rsa = d2i_RSAPrivateKey(&rsa, &private_key_bytes, private_key_length);
    printf("d2i_RSAPrivateKey(&rsa, &private_key_bytes, private_key_length) != NULL -> %s\n", (rsa != NULL) ? "true" : "false");

    getchar();

    return 0;
}

我在做什么错了?

What am I doing wrong?

推荐答案

TLDR d2i_RSA_PUBKEY d2i_RSAPrivateKey 应该工作,并为我做在Unix上。

TLDR: d2i_RSA_PUBKEY and d2i_RSAPrivateKey should work, and do for me on Unix.

您说要DER-CN codeD键(PKCS#1)。

You say you want 'DER-encoded keys (PKCS#1)'.

有关publickeys OpenSSL的通常使用的 SubjectPublicKeyInfo进行在X.509中定义的格式,其中包含一个为AlgorithmIdentifier 加上的包含在根据不同的算法不同而不同结构的公钥值的字节串。对于RSA,在寒冷的包含一个OID识别RSA和无参数;该算法依赖结构的PKCS#1。

For publickeys OpenSSL normally uses the format defined in X.509 as SubjectPublicKeyInfo which contains an AlgorithmIdentifier plus an OCTET STRING containing a publickey value in a structure that varies depending on the algorithm. For RSA, the algid contains an OID identifying RSA and no parameters; the algorithm-dependent structure is PKCS#1.

在此相反,OpenSSL的支持两种类型的privatekey格式:对于每种算法(DH除外),这对于RSA的PKCS#1'遗产'格式;和PKCS#8中定义一个通用的格式,它像SPKI由一个为AlgorithmIdentifier 加的算法依赖privatekey价值。 PKCS#8也有一个选项来加密密钥,这SPKI没有或需要。

In contrast, OpenSSL supports two types of privatekey format: there is a 'legacy' format for each algorithm (except DH), which for RSA is PKCS#1; and a generic format defined by PKCS#8 which like SPKI consists of an AlgorithmIdentifier plus an algorithm-dependent privatekey value. PKCS#8 also has an option to encrypt the key, which SPKI doesn't have or need.

的OpenSSL较旧的部分,包括 genrsa RSA 命令行实用工具,利用传统privatekey格式,但SPKI公钥格式,OpenSSL的名称PUBKEY。因此,你的 RSA 命令创建一个公钥文件可读 d2i_RSA_PUBKEY 而不是 d2i_RSAPublicKey (这将是只有PKCS#1份),并当作privateKey文件可读 d2i_RSAPrivateKey

Older parts of OpenSSL, including the genrsa and rsa commandline utilities, use legacy privatekey format, but SPKI publickey format which OpenSSL names PUBKEY. Thus your rsa commands created a publickey file readable by d2i_RSA_PUBKEY but not d2i_RSAPublicKey (which would be only the PKCS#1 part) and a privatekey file readable by d2i_RSAPrivateKey.

如果你真正需要的'裸'PKCS#1格式的公钥,在 RSA 实用程序有选择 -RSAPublicKey_in -RSAPublicKey_out 来读取和写入这种格式1.0.0以来,虽然在帮助消息最近才记录,仍然没有。这个文件将是 d2i_RSAPublicKey 而不是 d2i_RSA_PUBKEY 可读。

If you truly need publickey in 'bare' PKCS#1 format, the rsa utility has options -RSAPublicKey_in and -RSAPublicKey_out to read and write this format since 1.0.0, although documented only recently and still not in the help message. That file will be readable by d2i_RSAPublicKey but not d2i_RSA_PUBKEY.

一种可能性:你不提操作系统。 DER文件是二进制,并且在C正确处理Windows的二进制文件必须的fopen B 修改,在这里你想要RB读二进制文件。如果我运行code在Unix它的工作原理,但要获得在Windows上正确的结果,我必须添加 B

One possibility: you don't mention operating system. DER files are binary, and in C to correctly handle binary files on Windows you must fopen with the b modifier, here you want "rb" for read binary. If I run your code on Unix it works, but to get correct results on Windows I must add the b.

另外一个小点:请您谈谈内容加载中...的char *变量。其实你该文件的内容加载到内存中,并使用的char * 变量指向他们。严格地说,OpenSSL的 d2i 程序需要一个的地址常量无符号字符* 变量 - 和你的编译器应该警告你对于这种不匹配,至少如果你在一个符合标准的模式下运行它。但C要求​​指针均字符香精(签署 无符号和平原),有或没有资质,具有相同的重presentation和对齐要求,即使他们不兼容的标准定义,因此通过的char ** ,其中 const的无符号字符** 预计不会工作。

Also a minor point: you talk about 'loading contents ... in char* variables'. Actually you load the file contents into memory and use a char * variable to point to them. Strictly speaking, OpenSSL d2i routines want the address of a const unsigned char * variable -- and your compiler should warn you about this mismatch at least if you run it in a standard-conforming mode. But C requires pointers to all char flavors (signed unsigned and 'plain'), with or without qualification, to have the same representation and alignment requirements, even though they aren't compatible as defined in the standard, so passing char ** where const unsigned char ** is expected does work.

这篇关于d2i_RSA_PUBKEY,d2i_RSAPrivateKey和d2i_RSAPublicKey返回NULL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆