C 解密使用包含空密码短语的加密私钥

C 解密使用包含空密码短语的加密私钥,c,openssl,C,Openssl,我有以下(非常简化的)代码,它使用OpenSSL生成加密私钥,使用包含null的字符串作为密码短语: #include <stdio.h> #include <openssl/rsa.h> #include <openssl/evp.h> int main(int argc, char *argv[]) { char password[32] = "pass\000word"; extern FILE *stdout; EVP_PKEY

我有以下(非常简化的)代码,它使用OpenSSL生成加密私钥,使用包含
null
的字符串作为密码短语:

#include <stdio.h>
#include <openssl/rsa.h>
#include <openssl/evp.h>
int main(int argc, char *argv[]) {
    char password[32] = "pass\000word";
    extern FILE *stdout;
    EVP_PKEY *key = NULL;
    RSA *rsa;

    SSL_library_init();
    OpenSSL_add_all_algorithms();

    rsa = RSA_generate_key(2048, RSA_F4, NULL, NULL);
    key = EVP_PKEY_new();

    EVP_PKEY_assign(key, EVP_PKEY_RSA, rsa);

    /* Write the private key to the file */
    PEM_write_PrivateKey(stdout, key, EVP_des_ede3_cbc(), (unsigned char*)password, 32, NULL, NULL);
    return 0;
}
据我所见,
PEM_read_PrivateKey
只接受以
null
结尾的密码短语,这与
PEM_write_PrivateKey
不同


如何解密生成的密钥?

使用调用者提供的回调来执行密码设置。以下内容是完全暴力的、可怕的、没有错误检查的,也绝不是我的编码习惯的典范,但展示了我所指的内容:

#include <stdio.h>
#include <string.h>
#include <openssl/rsa.h>
#include <openssl/evp.h>
#include <openssl/pem.h>

int password_cb (char *buf, int size, int rwflag, void *userdata)
{
    memcpy(buf, userdata, 32);
    return 32;
}

int main(int argc, char *argv[])
{
    char password[32] = "pass\0word";
    EVP_PKEY *key = NULL;
    RSA *rsa;

    OpenSSL_add_all_algorithms();

    rsa = RSA_generate_key(2048, RSA_F4, NULL, NULL);
    key = EVP_PKEY_new();

    EVP_PKEY_assign(key, EVP_PKEY_RSA, rsa);

    /* Write the private key to the file */
    FILE *fp = fopen("somekey.pem", "w");
    PEM_write_PrivateKey(fp, key, EVP_aes_128_cbc(), (unsigned char*)password, sizeof(password), NULL, NULL);
    fclose(fp);


    EVP_PKEY* rdkey = NULL;
    fp = fopen("somekey.pem", "r");
    PEM_read_PrivateKey(fp, &rdkey, password_cb, password);
    fclose(fp);

    PEM_write_PrivateKey(stdout, key, NULL, NULL, 0, NULL, NULL);
    PEM_write_PrivateKey(stdout, rdkey, NULL, NULL, 0, NULL, NULL);

    return 0;
}

希望这就是您想要的。

您是否尝试使用实际的密码回调而不是NULL并提供密码短语?cb参数的文档(更重要的是,省略它)非常清楚:“如果cb参数设置为NULL且u参数不为NULL,则u参数将被解释为以NULL结尾的字符串,用作密码短语。如果cb和u都为NULL,则使用默认的回调例程,该例程通常会在关闭回显的情况下提示在当前终端上输入密码短语“。我还没有尝试过自定义回调函数,而使用终端的默认回调函数似乎忽略了空值。我会看看我能不能抽一些定制的,然后回来汇报。这似乎很管用。我没有想到使用回调。因为羞愧。我将尝试解决我的现实问题,并在可行时批准答案。谢谢
#include <stdio.h>
#include <string.h>
#include <openssl/rsa.h>
#include <openssl/evp.h>
#include <openssl/pem.h>

int password_cb (char *buf, int size, int rwflag, void *userdata)
{
    memcpy(buf, userdata, 32);
    return 32;
}

int main(int argc, char *argv[])
{
    char password[32] = "pass\0word";
    EVP_PKEY *key = NULL;
    RSA *rsa;

    OpenSSL_add_all_algorithms();

    rsa = RSA_generate_key(2048, RSA_F4, NULL, NULL);
    key = EVP_PKEY_new();

    EVP_PKEY_assign(key, EVP_PKEY_RSA, rsa);

    /* Write the private key to the file */
    FILE *fp = fopen("somekey.pem", "w");
    PEM_write_PrivateKey(fp, key, EVP_aes_128_cbc(), (unsigned char*)password, sizeof(password), NULL, NULL);
    fclose(fp);


    EVP_PKEY* rdkey = NULL;
    fp = fopen("somekey.pem", "r");
    PEM_read_PrivateKey(fp, &rdkey, password_cb, password);
    fclose(fp);

    PEM_write_PrivateKey(stdout, key, NULL, NULL, 0, NULL, NULL);
    PEM_write_PrivateKey(stdout, rdkey, NULL, NULL, 0, NULL, NULL);

    return 0;
}