2017-03-23 2 views
1

libcryptoのOpenSSLを使用して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 

をRSA秘密鍵と公開鍵を生成したI暗号化されたファイルを解読するプログラムを以下に書きました。しかし、復号化が期待どおりに動作していないように見えました。

#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; 

} 

コードを実行する場合、結果は復号化されたデータの長さが正しいと印刷可能ではないではなかったように見えた

[[email protected] ~]$ ./test 
Initialize crypto library done 
load private key successfully 
data input length is 256 
outlen is 256 
decrypted data 

、以下の通りです。

"EVP_PKEY_CTX_set_rsa_padding(ctx、RSA_NO_PADDING);"という命令をコメントアウトしたところ、うまくいきました。

RSA_PKCS1_OAEP_PADDINGでも試してみましたが、うまくいきませんでした。 RSA PADDINGが設定されていないと、動作します。

私の質問は、以下のようにコマンドを次のように使用されているパディング

  1. のですか?

    openssl pkeyutl -encrypt -pubin -inkey ~/pub.key -in ~/1.txt -out ~/1e.txt 
    
  2. RSA暗号化/復号化にパディングが必要ですか?もしそうなら、どうすればパディングメカニズムを適用できますか?

+0

[documentation](https://www.openssl.org/docs/man1.1.0/apps/pkeyutl.html)では、デフォルトでどの埋め込みが使用されているかはわかりません。私はそれがPKCS#1パディングだと思います。 @ArtjomB。 –

+0

最初にPKCS#1パディングを使用して復号しようとしましたが、動作しませんでした。 次に、パディングは使用されていないと推測し、RSA_NO_PADDINGを使用して復号化しましたが、どちらも機能しませんでした。しかし、私がrsa_paddingの設定に関するコメントをした後、それはうまくいった。私のコードは今でも動作しますが、私はまだそれほど理由を理解していません。 @ArtjomB。 – Jared

+0

私はopensslソースコードをチェックしました。 PKCS#1はデフォルトのパディングモードです。 – Jared

答えて

0

openssl pkeyutl暗号化でデフォルトのパディングを使用しない場合は、EVP_PKEY_CTX_set_rsa_paddingを使用する必要があります。 -rsa_padding_modeの詳細については、openssl pkeyutl documentationを参照してください。

+1

あなたの説明をありがとう。私はソースコードをチェックし、PKCS#1はデフォルトのパディングモードです。 – Jared