C++ 使用openssl libcrypto使用RSA私钥解密数据时使用RSA_NO_填充

C++ 使用openssl libcrypto使用RSA私钥解密数据时使用RSA_NO_填充,c++,encryption,openssl,rsa,libcrypto,C++,Encryption,Openssl,Rsa,Libcrypto,我生成了RSA私钥和公钥,如下所示 openssl genpkey -algorithm RSA -out key.pem -pkeyopt rsa_keygen_bits:2048 openssl rsa -pubout -in pri.key -out pub.key openssl pkeyutl -encrypt -pubin -inkey ~/pub.key -in ~/1.txt -out ~/1e.txt [stack@agent ~]$ ./test Initialize c

我生成了RSA私钥和公钥,如下所示

openssl genpkey -algorithm RSA -out key.pem -pkeyopt rsa_keygen_bits:2048
openssl rsa -pubout -in pri.key -out pub.key
openssl pkeyutl -encrypt -pubin -inkey ~/pub.key -in ~/1.txt -out ~/1e.txt
[stack@agent ~]$ ./test
Initialize crypto library done
load private key successfully
data input length is 256
outlen is 256
decrypted data
和加密文本文件,如下所示

openssl genpkey -algorithm RSA -out key.pem -pkeyopt rsa_keygen_bits:2048
openssl rsa -pubout -in pri.key -out pub.key
openssl pkeyutl -encrypt -pubin -inkey ~/pub.key -in ~/1.txt -out ~/1e.txt
[stack@agent ~]$ ./test
Initialize crypto library done
load private key successfully
data input length is 256
outlen is 256
decrypted data
然后我写了下面的程序来解密加密文件。然而,解密似乎并没有像预期的那样起作用

#include <openssl/evp.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/conf.h>
#include <iostream>

using namespace std;

void
cleanup()
{
    EVP_cleanup();
    CRYPTO_cleanup_all_ex_data();
    ERR_free_strings();
}

int
main(int argc, char** argv)
{
    ERR_load_crypto_strings();
    OpenSSL_add_all_algorithms();
    OPENSSL_config(nullptr);

    cout<<"Initialize crypto library done"<<endl;

    EVP_PKEY * key = EVP_PKEY_new();
    if (key == nullptr) {
        cout<<"Failed to contruct new key"<<endl;
        return 1;
    }
    FILE * fpri = nullptr;
    fpri = fopen("/home/stack/pri.key", "r");
    if (fpri == nullptr) {
        cout<<"Failed to load private key"<<endl;
        return 1;
    }
    key = PEM_read_PrivateKey(fpri, &key, nullptr, nullptr);
    if (key == nullptr) {
        std::cout<<"Read private key failed"<<endl;
        return 1;
    }
    cout<<"load private key successfully"<<endl;
    EVP_PKEY_CTX *ctx = nullptr;
    ctx = EVP_PKEY_CTX_new(key, nullptr);
    EVP_PKEY_decrypt_init(ctx);
    EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_NO_PADDING);

    size_t outlen = 0, inlen = 0;
    unsigned char * out = nullptr, * in = nullptr;

    char buf[1024];
    FILE * fe = nullptr;
    fe = fopen("/home/stack/1e.txt", "r");
    size_t len = fread(buf, 1, sizeof(buf),  fe);
    cout<<"data input length is "<<len<<endl;
    EVP_PKEY_decrypt(ctx, NULL, &outlen, in, inlen);
    cout<<"outlen is "<<outlen<<endl;

    out = (unsigned char*)OPENSSL_malloc(outlen);
    EVP_PKEY_decrypt(ctx, out, &outlen, in, inlen);
    cout<<"decrypted data "<<out<<endl;
    cleanup();

    return 0;

}
解密的数据长度似乎不正确,无法打印

当我注释掉指令“EVP_PKEY_CTX_set_rsa_padding(CTX,rsa_NO_padding);”时,它运行良好

我还尝试了RSA_PKCS1_OAEP_填充,但也不起作用。如果未设置RSA填充,则它会起作用

我的问题如下:

openssl genpkey -algorithm RSA -out key.pem -pkeyopt rsa_keygen_bits:2048
openssl rsa -pubout -in pri.key -out pub.key
openssl pkeyutl -encrypt -pubin -inkey ~/pub.key -in ~/1.txt -out ~/1e.txt
[stack@agent ~]$ ./test
Initialize crypto library done
load private key successfully
data input length is 256
outlen is 256
decrypted data
  • 以下命令中使用了哪个填充

    openssl pkeyutl -encrypt -pubin -inkey ~/pub.key -in ~/1.txt -out ~/1e.txt
    
  • RSA加密/解密是否需要填充?如果是,我如何应用填充机制


  • 如果在openssl pkeyutl加密中使用非默认填充,则应使用
    EVP_PKEY_CTX_set_rsa_padding
    。有关
    -rsa_padding_mode

    的详细信息,请参阅。如果在openssl pkeyutl加密中使用非默认填充,则应使用
    EVP_PKEY_CTX_set_rsa_padding
    。有关
    -rsa\u padding\u mode

    的详细信息,请参阅,其中没有说明默认情况下使用的填充。我想是PKCS#1。@ArtjomB。我尝试先用PKCS#1填充来解密,但没有成功。然后我猜没有使用填充,使用RSA_no_填充来解密,它也不起作用。但是在我对设置rsa_填充的指令进行了注释之后,它起到了作用。虽然我的代码现在可以工作了,但我仍然不太明白为什么。@ArtjomB。我检查了openssl源代码。我现在明白了,PKCS#1是默认的填充模式。如果您仔细研究代码,那么您可能会提供比当前接受的答案更广泛的答案。仔细想想,它并没有说默认情况下使用哪种填充。我想是PKCS#1。@ArtjomB。我尝试先用PKCS#1填充来解密,但没有成功。然后我猜没有使用填充,使用RSA_no_填充来解密,它也不起作用。但是在我对设置rsa_填充的指令进行了注释之后,它起到了作用。虽然我的代码现在可以工作了,但我仍然不太明白为什么。@ArtjomB。我检查了openssl源代码。我现在明白了,PKCS#1是默认的填充模式。如果您仔细研究代码,那么您可能会提供比当前接受的答案更广泛的答案。想一想,谢谢你的解释。我检查了源代码,PKCS#1是默认的填充模式。谢谢你的解释。我检查了源代码,PKCS#1是默认的填充模式。