openssl - 从整数加载 rsa 私钥并在 openssl 中转换为 PEM 格式或 RSA 结构以签署消息

标签 openssl rsa pem

我有 RSA key 的公共(public)指数(e)、(n) 和私有(private)指数(d),如何才能我将它们转换为 PEM 格式的 RSA key 或 openssl 中定义的 RSA 结构?

我想使用 openssl 使用 RSA 私钥对文本进行签名,可以使用 C 代码或 openssl 实用程序。

我在网上搜索过,有很多帖子可以从PEM key 中提取参数,但未能找到有关如何使用将它们转换回PEM的有用信息C。看来这不是常见的情况......

编辑:抱歉,标题有点误导,我的最终目的是用它来签署消息(如描述中所述)

最佳答案

RSA 数学仅需要 nd 来实现签名。此外,OpenSSL 的实现也只需要 nd 来进行签名。您可以直接在 RSA 结构中设置这些值。此示例仅显示“...在 C 代码中使用 openssl ... 使用 RSA 私钥签名文本”的示例,并忽略您的 PEM 查询。

#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>
#include <openssl/bn.h>
#include <openssl/evp.h>

static void printerrors() {
    char errbuf[1024];
    while (1) {
        unsigned long error = ERR_get_error();
        if (error == 0) {
            break;
        }
        ERR_error_string(error, errbuf);
        fputs(errbuf, stderr);
    }
    fflush(stderr);
}

static void sign(RSA *rsa, const char *message) {
    EVP_PKEY *pkey = EVP_PKEY_new();
    if (!EVP_PKEY_set1_RSA(pkey, rsa)) goto err;
    EVP_MD_CTX *ctx = EVP_MD_CTX_create();
    if (!EVP_DigestSignInit(ctx, NULL, EVP_sha256(), NULL, pkey)) goto err;
    if (!EVP_DigestSignUpdate(ctx, (const void * ) message, strlen(message))) goto err;
    size_t siglen;
    if (!EVP_DigestSignFinal(ctx, NULL, &siglen)) goto err;
    unsigned char *signature = malloc(siglen);
    if (signature == NULL) goto err;

    if (!EVP_DigestSignFinal(ctx, signature, &siglen)) goto err;

    for (int i = 0; i < siglen; i++) {
        printf("%02x", signature[i]);
    }
    printf("\n");
    free(signature);
    EVP_MD_CTX_destroy(ctx);
    EVP_PKEY_free(pkey);

    return;
err:
    printerrors();
    exit(1);
}

int main(int argc, char *argv[]) {
    const int BITS = 1024;
    const int PUBLIC_EXPONENT = 65537;
    OpenSSL_add_all_algorithms();
    RSA *rsa = RSA_generate_key(BITS, PUBLIC_EXPONENT, NULL, NULL);

    RSA *rsa2 = RSA_new();
    rsa2->n = BN_dup(rsa -> n);
    rsa2->e = BN_dup(rsa -> e);
    rsa2->d = BN_dup(rsa -> d);

    RSA_print_fp(stdout, rsa2, 0);
    sign(rsa2, "Sign me, please");
    RSA_free(rsa2);
    RSA_free(rsa);
}

通常与私钥关联的其他值,pq等并不是严格必需的。如果存在,它们可用于加速私钥操作,包括利用中国剩余定理进行签名。此外,如果需要,它们可以轻松地从 nde 派生出来:例如参见 section 8.2.2 (i) of the Handbook Of Applied Cryptography .

关于openssl - 从整数加载 rsa 私钥并在 openssl 中转换为 PEM 格式或 RSA 结构以签署消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29313268/

相关文章:

visual-studio - PEM_read_bio_X509(有时)失败(OpenSSL 1.0.1p)

c++ - 编译带有 openSSL 错误的静态 Qt

java - 如何使用 RSA 加密对 http 响应进行加密

python - 在python中使用SMTP_SSL发送邮件

python - 在 Python 中读取证书

ssh - 将 PEM 转换为 PPK 文件格式

security - 通过 SSL 的 RabbitMQ

c++ - 构建 ACE_SSL

iphone - 将 RSA 公钥发送到 iphone 并使用它来加密

swift - 使用 SwiftyRSA 的 RSA 加密