仅使用模数的RSA公钥转换

时间:2015-02-27 17:02:43

标签: c openssl rsa public-key

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

我认为这是DER格式,但我不是百分之百确定。

1 个答案:

答案 0 :(得分:4)

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

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对象,并设置公共指数(rsa->e)和模数(rsa->n)。

最后,我将RSA公钥写入包含PEM_write_RSAPublicKey的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-----