【问题标题】:How do I decrypt a private key file and sign some text using openssl calls in C?如何在 C 中使用 openssl 调用解密私钥文件并签署一些文本?
【发布时间】:2010-12-01 00:48:06
【问题描述】:

我有 2 个单独的程序(下面拼接在一起)。第一个生成密钥对并保存到文件中(工作正常)。第二个打开私钥,用密码短语解密,然后我需要它来签署一串文本。下面的代码在 PEM_read_PrivateKey() (最后一次)调用中失败(不明白为什么)。谁能指出我做错了什么,然后我应该进行什么 openssl 调用以使用私钥签署一些文本?

int main (int argc, char *argv[])
{
    char *priv_pem = "priv.pem";
    char *pub_pem  = "pub.pem";
    char *pass     = "Password";
    FILE *fp;   
    int bits = 4096;
    unsigned long exp = RSA_F4;

    RSA *rsa;
    EVP_PKEY *pkey;

    //  GENERATE KEY
    rsa=RSA_generate_key(bits,exp,NULL,NULL);
    if (RSA_check_key(rsa)!=1)
        Exit(1,"Error whilst checking key","");
    pkey = EVP_PKEY_new();
    EVP_PKEY_assign_RSA(pkey, rsa);

    //  WRITE ENCRYPTED PRIVATE KEY
    if (!(fp = fopen(priv_pem, "w")))
        Exit(2,"Error opening PEM file",priv_pem);
    if (!PEM_write_PrivateKey(fp,pkey,EVP_aes_256_cbc(),NULL,0,NULL,pass))
        Exit(3,"Error writing PEM file",priv_pem);
    fclose(fp);

    //  WRITE PUBLIC KEY
    if (!(fp = fopen(pub_pem, "w")))
        Exit(4,"Error opening PEM file",pub_pem);
    if (!PEM_write_PUBKEY(fp, pkey))
        Exit(5,"Error writing PEM file",pub_pem);
    fclose(fp);
    // ------- End of key generation program -------

    // ------- Start of text signing program -------
    //  READ IN ENCRYPTED PRIVATE KEY
    if (!(fp = fopen(priv_pem, "r")))
        Exit(6,"Error reading encrypted private key file",priv_pem);
    if (!PEM_read_PrivateKey(fp,&pkey,NULL,pass))
        Exit(7,"Error decrypting private key file",priv_pem);
    fclose(fp);

    // Sign some text using the private key....

    //  FREE
    RSA_free(rsa);  
    return 0;
}

【问题讨论】:

    标签: c cryptography openssl


    【解决方案1】:

    在将&pkey 传递给PEM_read_PrivateKey() 之前,您是否已将pkey 初始化为NULL?如果不是,它将尝试重新使用pkey 指向的EVP_PKEY 结构,如果pkey 未初始化,它将查看内存中的随机点。

    当发生错误时,您可以使用 ERR_print_errors_fp(stderr); 将 OpenSSL 错误堆栈转储到 stderr - 这通常有助于发现问题。

    【讨论】:

    • 我添加了 pkey = NULL;在 PEM_read_PrivateKey() 之前。它仍然有错误和 ERR_print_errors_fp(stderr);显示:
    • 2732:error:0906B072:lib(9):func(107):reason(114):.\crypto\pem\pem_lib.c:481:
    • 我刚刚查看了 pem.lib 并且错误发生在 PEM_get_EVP_CIPHER_INFO 中,这是因为它不知道 EVP_CIPHER 是什么。如何在 PEM_read_PrivateKey() 调用之前关联 EVP_aes_256_cbc() 密码?
    • @Steve:这似乎是一个“不支持的算法”错误。您应该使用 PEM_write_PKCS8PrivateKey() 来编写密钥 - PEM_write_PrivateKey() 已被弃用,这可能是问题所在(尝试使用带有 AES 256 的旧格式?)
    • @caf:我更改了对 PEM_write_PKCS8PrivateKey(same args) 的调用,现在该调用出错:732:error:06074079:lib(6):func(116):reason(121) :.\crypto\evp\evp_pbe.c:89:TYPE=PBES2 732:error:23077073:lib(35):func(119):reason(115):.\crypto\pkcs12\p12_decr.c:83:732 :error:2306C067:lib(35):func(108):reason(103):.\crypto\pkcs12\p12_decr.c:168: 732:error:2307D067:lib(35):func(125):reason( 103):.\crypto\pkcs12\p12_p8e.c:88:
    【解决方案2】:

    感谢@caf 的帮助。 通过反复试验,我通过在开头添加以下内容来修复 PEM_read_PrivateKey() 错误:

    if (EVP_get_cipherbyname("aes-256-cbc") == NULL)
        OpenSSL_add_all_algorithms();
    

    但是,我仍在寻找生成密钥然后使用私钥进行签名的最佳(实践)方法。根据我有限的理解,我正在寻找符合 RSA 的“PKCS #1 v2.0: RSA Cryptography Standard”的 openssl 方法

    【讨论】:

    • 经过数小时的调试节省了我的一天,12 岁的答案。 :D
    猜你喜欢
    • 2020-03-06
    • 2020-02-28
    • 2017-07-07
    • 2011-10-15
    • 2021-02-17
    • 2021-02-02
    • 2012-04-07
    • 2013-07-15
    • 1970-01-01
    相关资源
    最近更新 更多