Команда OpenSSL в c, чтобы получить модуль открытого ключа в RSA

Мы хотели найти метод OpenSSl в C, который дает нам только модуль из открытого ключа, использующего RSA. Однако мы не уверены, какой метод использовать. Работает ли функция d2i_RSAPublicKey, но мы не уверены, какие аргументы она принимает? '

Что такое метод c для следующей команды open ssl, которая извлекает только модуль:

$ openssl ssl rsa -inform der -pubin -text < 12120862.key 
Public-Key: (1024 bit)
Modulus:
    00:81:1f:1d:00:7e:d0:c7:e2:2f:31:3d:0d:f0:a8:
    ab:c1:ea:66:ba:af:1d:a4:eb:b3:fd:51:58:1c:1d:
    81:ae:f0:99:9e:5c:26:67:b5:41:14:28:79:c0:29:
    e5:56:96:06:b7:4b:a0:c9:7f:41:46:9a:7e:85:10:
    a0:91:ea:58:bd:78:78:6d:3c:07:2a:3d:61:f3:ed:
    42:8b:1e:dc:6d:2d:21:41:7a:e8:15:51:0d:75:84:
    be:20:8c:76:43:8b:4b:67:6b:49:09:e9:20:a1:11:
    53:a0:d9:30:b1:c2:27:a6:09:e1:56:36:ed:7e:9b:
    23:e2:df:5b:bd:c5:66:ca:c5
Exponent: 65537 (0x10001)
writing RSA key

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCBHx0AftDH4i8xPQ3wqKvB6ma6
rx2k67P9UVgcHYGu8JmeXCZntUEUKHnAKeVWlga3S6DJf0FGmn6FEKCR6li9eHht
PAcqPWHz7UKLHtxtLSFBeugVUQ11hL4gjHZDi0tna0kJ6SChEVOg2TCxwiemCeFW
Nu1+myPi31u9xWbKxQIDAQAB
-----END PUBLIC KEY-----

2 ответа

Решение

Что такое метод c для следующей команды open ssl, которая извлекает только модуль

Краткий ответ... Учитывая RSA состав:

RSA* rsa = ...;
BIGNUM* n = rsa->n;

Затем используйте BN_print_fp:

BN_print_fp(stdout, n);

Или используйте BN_bn2dec:

fprintf(stdout, "%s", BN_bn2dec(n));

Или используйте ASN1_bn_print:

int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num,
                  unsigned char *buf, int off)

ASN1_bn_print от длинного ответа ниже, и он дает вам форматирование, которое вы показали в своем примере.


Длинный ответ... Я считаю, что ключ напечатан с RSA_print_fpи это в конечном итоге заканчивается призывами к ASN1_bn_print для различных параметров RSA. Вот часть тропы:

$ grep -R RSA_print_fp *
crypto/rsa/rsa.h:int    RSA_print_fp(FILE *fp, const RSA *r,int offset);
crypto/rsa/rsa_err.c:{ERR_FUNC(RSA_F_RSA_PRINT_FP), "RSA_print_fp"},
crypto/rsa/rsa_prn.c:int RSA_print_fp(FILE *fp, const RSA *x, int off)
...

Следующий RSA_print_fp:

int RSA_print_fp(FILE *fp, const RSA *x, int off)
{
    BIO *b;
    int ret;

    if ((b=BIO_new(BIO_s_file())) == NULL)
    {
        RSAerr(RSA_F_RSA_PRINT_FP,ERR_R_BUF_LIB);
        return(0);
    }
    BIO_set_fp(b,fp,BIO_NOCLOSE);
    ret=RSA_print(b,x,off);
    BIO_free(b);
    return(ret);
}

А также RSA_print:

int RSA_print(BIO *bp, const RSA *x, int off)
{
    EVP_PKEY *pk;
    int ret;
    pk = EVP_PKEY_new();
    if (!pk || !EVP_PKEY_set1_RSA(pk, (RSA *)x))
        return 0;
    ret = EVP_PKEY_print_private(bp, pk, off, NULL);
    EVP_PKEY_free(pk);
    return ret;
}

EVP_PKEY_print_private в crypto/evp/p_lib.c:

int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey,
                           int indent, ASN1_PCTX *pctx)
{
    if (pkey->ameth && pkey->ameth->priv_print)
        return pkey->ameth->priv_print(out, pkey, indent, pctx);

    return unsup_alg(out, pkey, indent, "Private Key");
}

Попав в "методы", не следуйте RSA_get_default_method, Скорее найди priv_print:

$ grep -R priv_print * | grep -i RSA
crypto/rsa/rsa_ameth.c:static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
crypto/rsa/rsa_ameth.c:     rsa_priv_print,

А также rsa_priv_print:

static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
                          ASN1_PCTX *ctx)
{
    return do_rsa_print(bp, pkey->pkey.rsa, indent, 1);
}

Следующий, do_rsa_print:

static int do_rsa_print(BIO *bp, const RSA *x, int off, int priv)
{
    ...
    str = "Modulus:";
    s = "Exponent:";

    if (!ASN1_bn_print(bp,str,x->n,m,off)) goto err;
    if (!ASN1_bn_print(bp,s,x->e,m,off)) goto err;

    if (priv)
    {
        if (!ASN1_bn_print(bp,"privateExponent:",x->d,m,off))
            goto err;
        if (!ASN1_bn_print(bp,"prime1:",x->p,m,off))
            goto err;
        if (!ASN1_bn_print(bp,"prime2:",x->q,m,off))
            goto err;
        if (!ASN1_bn_print(bp,"exponent1:",x->dmp1,m,off))
            goto err;
        if (!ASN1_bn_print(bp,"exponent2:",x->dmq1,m,off))
            goto err;
        if (!ASN1_bn_print(bp,"coefficient:",x->iqmp,m,off))
            goto err;
    }
    ...
}

Я оставлю финал ASN1_bn_print проследить до читателя. Добавляет двоеточия (:) и разрывы строк (\n). Вы можете найти это в crypto/asn1/t_pkey.c,


Вот как бы вы использовали ASN1_bn_print:

RSA* rsa = RSA_new();
...

BIO* bio = BIO_new_fp(stdout, BIO_NOCLOSE);
...

int req = BN_num_bytes(rsa->n) + 4;
ptr = OPENSSL_malloc(req);

rc = ASN1_bn_print(bio, "Modulus:", rsa->n, ptr, 0);
ASSERT(rc == 1);
...

Запуск программы, как указано выше, приведет к:

$ ./test-openssl.exe
Modulus:
    00:bb:bb:cf:ac:58:a9:25:2c:08:37:4d:4d:1d:0c:
    5b:7d:a7:ba:de:7b:31:9a:5e:40:61:1f:6d:de:f9:
    b4:48:15:a3:8c:2a:12:a9:10:fb:66:12:a4:3f:9c:
    0d:7f:80:94:b1:63:91:05:96:f0:48:e5:7d:76:8a:
    d0:26:dc:54:43

Я искал функцию переменного тока, которая возвращает struct rsa, принимая открытый ключ

Для этого вам, вероятно, нужно PEM_read_RSAPrivateKey а также PEM_read_PUBKEY, Также есть некоторые биологические чтения. Увидеть pem(3),

PEM_read_RSAPrivateKey возвращает RSA*,

PEM_read_PUBKEY возвращает EVP_PKEY*, Если это ключ RSA, то вы можете получить RSA* с EVP_PKEY_get1_RSA, get1 означает, что счетчик ссылок был увеличен, поэтому обязательно позвоните RSA_free в теме.

Чтобы определить, если EVP_PKEY* ключ RSA, используйте EVP_PKEY_get_type, Вы получите EVP_PKEY_RSA или же EVP_PKEY_RSA2,

Другие вопросы по тегам