将公钥加载到创建RSA对象以进行公共加密

3

我正在尝试从生成的公钥加载rsa对象。我使用PEM_write_bio_RSAPublicKey生成了公钥字符串。然后我使用PEM_read_bio_RSA_PUBKEY从公钥字符串中加载rsa对象。问题是rsa对象为空。据我所见,生成的字符串看起来没问题。有什么建议吗?

-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEAxIReUspesPy6a4CPBjt/4Jt+H13q9MekMiutzNKdNO1uuwqcdqDX
pKPeTKXyUH6oCyRdUxkk6IVXGlBlxtW7OsxaYWhpfl9z3CCERCEpFmzN++dvlK2v
mckFL66e9q6Y+HwgyP1LJqrszeqlg2d29TCVKfD/UURVNmc/nPPjs9nO+IDhh7+P
NTQ2OqGBq8ghwVL5ZZyW3yVO5OAbRB6pjKBe9+j4B2TGnD5JO9Nu0jlFANZOKFJu
HDVE3XuTvOkuzL2i8Lwp4Myk42tbIgcCe4G58vKFddL651rWhg4hN3fRSx5YtDnQ
r5cgfNBOAww58S8lwXgU8lvzvEoNV+WMgwIDAQAB
-----END RSA PUBLIC KEY-----

gcc test_public_private_key.c -lcrypto -o test

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>

char* get_public_key() {

        RSA* rsa = RSA_new();
        int kbits = 2048;
        BIGNUM* bne = BN_new();
        BN_set_word(bne, RSA_F4);

        int status = RSA_generate_key_ex(rsa, kbits, bne, NULL);
        if(status == 0) {
                fprintf(stderr, "rsa key generation failed\n");
        }


        BIO *bio = BIO_new(BIO_s_mem());
        PEM_write_bio_RSAPublicKey(bio, rsa);

        int length = BIO_pending(bio);

        char* pem_key = malloc(length+1);
        memset(pem_key, '\0', length+1);

        BIO_read(bio, pem_key, length);

        return pem_key;

}

int main(int argc, char* argv[]) {

        char* public_key = get_public_key();

        printf("%s", public_key);

        BIO* keybio = BIO_new_mem_buf(public_key, -1);

        if (keybio == NULL) {
                fprintf(stderr, "failed to create key BIO");
        }

        printf("keybio: %p\n", keybio);
        RSA* rsa = PEM_read_bio_RSA_PUBKEY(keybio, NULL, NULL, NULL);
        printf("rsa result %p\n", rsa);
        BIO_free(keybio);

        free(public_key);

        return 0;
}

我记得看到一个使用BIO_FLAGS_BASE64_NO_NL标志的工作示例。也许尝试使用BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);来设置此标志。 - Daniel
@Daniel,我不确定它是否应该包含RSA这个词...它是库自己生成字符串的函数。我通过谷歌搜索看到了NL的例子,但如果我使用该选项,那么这是否意味着我应该从生成的字符串中去掉换行符。 - eat_a_lemon
我尝试了使用NO_NL选项,有时去掉换行符,但仍然无效。 - eat_a_lemon
经过进一步查看,我相当确定 RSA 单词应该在那里。至于标志,我看到它与具有换行符的密钥一起使用,但再次查看并阅读 BIO_set_flags 的内容后,我认为它可能是无关紧要的,因为我认为它仅用于 BIO_write 方法中。你可以尝试一下,看看是否有效。你还应该尝试使用 openssl 命令生成的密钥,并将其硬编码,看看是否可以使用它。 - Daniel
我使用了openssl命令来生成公钥,但RSA单词不在那里。我尝试了相同的操作,结果还是空的。 - eat_a_lemon
显示剩余3条评论
1个回答

3
我认为加上这个说明很好,因为这个方法不起作用的原因是PEM_read_RSA_PUBKEY需要一个以BEGIN PUBLIC KEY开头的SubjectPublicKeyInfo结构,而PEM_read_RSAPublicKey需要一个以BEGIN RSA PUBLIC KEY开头的RSAPublicKey结构。
PEM_write_bio_RSAPublicKey生成了后者,对应于第二个函数PEM_read_RSAPublicKey

RSA_generate_key_ex creates the in-memory form; it is PEM_write_[bio_]RSAPublicKey (in OP's get_public_key) that creates the PKCS1 form which is readable by PEM_read_[bio_]RSAPublicKey but not PEM_read_[bio_][RSA_]PUBKEY - dave_thompson_085
@dave_thompson_085 哦,是的,我的错。我编辑了我的回答,非常感谢你。 - Daniel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接