RSA Public 仅使用模数的密钥转换

RSA Public Key Conversion with just Modulus

我收到了一个 RSA-2048 位 public 密钥(256 字节)作为一个文件,其中只包含这 256 个字节。 SSL 中的哪个函数使我能够将此密钥作为 RSA 结构加载,以便我可以将其转换为另一种格式?这是使用 openssl 源代码的 C 代码。

我认为是 DER 格式,但我不是 100% 确定。

我只是把它放在一起,它似乎工作正常:

https://github.com/JonathonReinhart/rawrsa

#include <stdio.h>
#include <stdlib.h>
#include <libgen.h>
#include <openssl/bn.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>

static const char* appname;

static void print_bn(const char *what, const BIGNUM *bn)
{
#ifdef DEBUG
    char *str = BN_bn2hex(bn);
    printf("%s (hex): %s\n", what, str);
    OPENSSL_free(str);
#endif
}

static void usage(void)
{
    fprintf(stderr, "Usage: %s modulus-file exponent\n", appname);
}

#define err(fmt, ...)   \
    fprintf(stderr, "%s: " fmt, appname, ##__VA_ARGS__)

int main(int argc, char *argv[])
{
    appname = basename(argv[0]);

    if (argc < 3) {
        usage();
        exit(1);
    }

    const char *modfile = argv[1];
    const char *expstr = argv[2];

    /* Read modulus */
    FILE *mf = fopen(modfile, "rb");
    if (!mf) {
        err("Failed to open \"%s\": %m\n", modfile);
        return 1;
    }

    unsigned char buf[256];
    if (fread(buf, sizeof(buf), 1, mf) != 1) {
        err("Failed to read %zu bytes of modulus\n", sizeof(buf));
        return 1;
    }

    fclose(mf);

    BIGNUM *mod = BN_bin2bn(buf, sizeof(buf), NULL);
    if (!mod) {
        err("BN_bin2bn() failed\n");
        return 1;
    }
    print_bn("Modulus", mod);


    /* Parse exponent */
    BIGNUM *exp = NULL;
    if (BN_dec2bn(&exp, expstr) == 0) {
        err("BN_dec2bn() failed\n");
        return 1;
    }
    print_bn("Exponent", exp);

    /* Create RSA key */
    RSA *rsa = RSA_new();
    if (!rsa) {
        err("RSA_new() failed\n");
        return 1;
    }
    rsa->e = exp;
    rsa->n = mod;

    /* Write PEM-encoded RSA public key to stdout */
    if (!PEM_write_RSAPublicKey(stdout, rsa)) {
        err("PEM_write_RSAPublicKey() failed\n");
        return 1;
    }

    return 0;
}

我使用 BN_bin2bn 从文件的原始二进制数据创建 OpenSSL bignum。这是我们加载 256 字节模数的地方。

然后,我使用 BN_dec2bn 从命令行提供的指数创建一个 bignum。

接下来,我使用 RSA_new 创建一个 RSA 对象,并设置 public 指数 (rsa->e) 和模数 (rsa->n)。

最后,我用 PEM_write_RSAPublicKey.

将 RSA public 密钥写入 PEM 文件

示例:

$ scons -Q
gcc -o main.o -c -Wall -Werror -g main.c
gcc -o rawrsa main.o -lcrypto

$ ./rawrsa key.bin 65537
-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEA9cFHSTQ6h1Ls/vx7B+V/84XVlLxUU1dU1mEr9ROAqWrZtfasvx2E
21lbva+AdJ/B4u6fGVhCEMgekXsRB65CqZfwL3DFL6tqam6GvrOyvZgAlQKrA54w
DaKMT8Kfg2I2K9W/HCkCOHczhuHhjFmeiV9BuQgpmcPcNz6UXBwU05d3g6oM/X4m
lEhEsaH4bqo1qsMX6jp6WnsR13GEfsYoYVmHgEbnKJyGpsoRVW6HQXLHvef9XLEJ
v9n7nLdHToya75svxJ3v9JugD3n6PiC48085/FWb9980o4hmG9iW5rehm4Dlui8c
TDnHkQSrvi9WLlZ+S8hdtwDRN/pVVTjgPAIDAQAB
-----END RSA PUBLIC KEY-----