2017-01-20 34 views
2

RSA暗号化を作成するサンプルプログラム(オンラインサンプルから取得)があります。RSA可変暗号化長

#include <cstring> 
#include <iostream> 
#include <openssl/pem.h> 
#include <openssl/rsa.h> 
#include <openssl/bio.h> 

RSA * createPublicRSA(unsigned char * key) 
{ 
    RSA * rsa= NULL; 
    BIO * keybio = BIO_new_mem_buf(key, -1); 
    rsa = PEM_read_bio_RSA_PUBKEY(keybio, &rsa, NULL, NULL); 
    return rsa; 
} 

int public_encrypt(unsigned char * data, int data_len, unsigned char * key, unsigned char * encrypted) 
{ 
    RSA * rsa = createPublicRSA(key); 
    int result = RSA_public_encrypt(data_len, data, encrypted, rsa, RSA_PKCS1_PADDING); 
    return result; 
} 

int main(int argc, char* argv[]) { 
    unsigned char publicKey[]="-----BEGIN PUBLIC KEY-----\n"\ 
           "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy8Dbv8prpJ/0kKhlGeJY\n"\ 
           "ozo2t60EG8L0561g13R29LvMR5hyvGZlGJpmn65+A4xHXInJYiPuKzrKUnApeLZ+\n"\ 
           "vw1HocOAZtWK0z3r26uA8kQYOKX9Qt/DbCdvsF9wF8gRK0ptx9M6R13NvBxvVQAp\n"\ 
           "fc9jB9nTzphOgM4JiEYvlV8FLhg9yZovMYd6Wwf3aoXK891VQxTr/kQYoq1Yp+68\n"\ 
           "i6T4nNq7NWC+UNVjQHxNQMQMzU6lWCX8zyg3yH88OAQkUXIXKfQ+NkvYQ1cxaMoV\n"\ 
           "PpY72+eVthKzpMeyHkBn7ciumk5qgLTEJAfWZpe4f4eFZj/Rc8Y8Jj2IS5kVPjUy\n"\ 
           "wQIDAQAB\n"\ 
           "-----END PUBLIC KEY-----\n"; 

    unsigned char plainText[2048/8] = "plain text"; //key length : 2048 
    size_t length = strlen(reinterpret_cast<const char*>(plainText)); 
    unsigned char encrypted[4098]= {}; 
    int encrypted_length = public_encrypt(plainText, length, publicKey, encrypted); 
    if (argc > 1) { 
     printf("Encrypted length: %d (Actual length: %lu)\n", encrypted_length, strlen(const_cast<const char*>(reinterpret_cast<char*>(encrypted)))); 
    } else { 
     std::cout << encrypted;  
    } 
} 

と秘密鍵は、次のとおりです。

-----BEGIN RSA PRIVATE KEY----- 
MIIEowIBAAKCAQEAy8Dbv8prpJ/0kKhlGeJYozo2t60EG8L0561g13R29LvMR5hy 
vGZlGJpmn65+A4xHXInJYiPuKzrKUnApeLZ+vw1HocOAZtWK0z3r26uA8kQYOKX9 
Qt/DbCdvsF9wF8gRK0ptx9M6R13NvBxvVQApfc9jB9nTzphOgM4JiEYvlV8FLhg9 
yZovMYd6Wwf3aoXK891VQxTr/kQYoq1Yp+68i6T4nNq7NWC+UNVjQHxNQMQMzU6l 
WCX8zyg3yH88OAQkUXIXKfQ+NkvYQ1cxaMoVPpY72+eVthKzpMeyHkBn7ciumk5q 
gLTEJAfWZpe4f4eFZj/Rc8Y8Jj2IS5kVPjUywQIDAQABAoIBADhg1u1Mv1hAAlX8 
omz1Gn2f4AAW2aos2cM5UDCNw1SYmj+9SRIkaxjRsE/C4o9sw1oxrg1/z6kajV0e 
N/t008FdlVKHXAIYWF93JMoVvIpMmT8jft6AN/y3NMpivgt2inmmEJZYNioFJKZG 
X+/vKYvsVISZm2fw8NfnKvAQK55yu+GRWBZGOeS9K+LbYvOwcrjKhHz66m4bedKd 
gVAix6NE5iwmjNXktSQlJMCjbtdNXg/xo1/G4kG2p/MO1HLcKfe1N5FgBiXj3Qjl 
vgvjJZkh1as2KTgaPOBqZaP03738VnYg23ISyvfT/teArVGtxrmFP7939EvJFKpF 
1wTxuDkCgYEA7t0DR37zt+dEJy+5vm7zSmN97VenwQJFWMiulkHGa0yU3lLasxxu 
m0oUtndIjenIvSx6t3Y+agK2F3EPbb0AZ5wZ1p1IXs4vktgeQwSSBdqcM8LZFDvZ 
uPboQnJoRdIkd62XnP5ekIEIBAfOp8v2wFpSfE7nNH2u4CpAXNSF9HsCgYEA2l8D 
JrDE5m9Kkn+J4l+AdGfeBL1igPF3DnuPoV67BpgiaAgI4h25UJzXiDKKoa706S0D 
4XB74zOLX11MaGPMIdhlG+SgeQfNoC5lE4ZWXNyESJH1SVgRGT9nBC2vtL6bxCVV 
WBkTeC5D6c/QXcai6yw6OYyNNdp0uznKURe1xvMCgYBVYYcEjWqMuAvyferFGV+5 
nWqr5gM+yJMFM2bEqupD/HHSLoeiMm2O8KIKvwSeRYzNohKTdZ7FwgZYxr8fGMoG 
PxQ1VK9DxCvZL4tRpVaU5Rmknud9hg9DQG6xIbgIDR+f79sb8QjYWmcFGc1SyWOA 
SkjlykZ2yt4xnqi3BfiD9QKBgGqLgRYXmXp1QoVIBRaWUi55nzHg1XbkWZqPXvz1 
I3uMLv1jLjJlHk3euKqTPmC05HoApKwSHeA0/gOBmg404xyAYJTDcCidTg6hlF96 
ZBja3xApZuxqM62F6dV4FQqzFX0WWhWp5n301N33r0qR6FumMKJzmVJ1TA8tmzEF 
yINRAoGBAJqioYs8rK6eXzA8ywYLjqTLu/yQSLBn/4ta36K8DyCoLNlNxSuox+A5 
w6z2vEfRVQDq4Hm4vBzjdi3QfYLNkTiTqLcvgWZ+eX44ogXtdTDO7c+GeMKWz4XX 
uJSUVL5+CVjKLjZEJ6Qc2WZLl94xSwL71E41H4YciVnSCQxVc4Jw 
-----END RSA PRIVATE KEY----- 

私は何回か

g++ encr.cpp -o encr -lcrypto -I/opt/local/include/ 

それを構築し、それを実行すると、私は、変数 "実際の長さ"

$ ./encr show-length 
Encrypted length: 256 (Actual length: 256) <--- Correct 
$ ./encr show-length 
Encrypted length: 256 (Actual length: 79) 
$ ./encr show-length 
Encrypted length: 256 (Actual length: 215) 
$ ./encr show-length 
Encrypted length: 256 (Actual length: 52) 
$ ./encr show-length 
Encrypted length: 256 (Actual length: 256) <--- Correct 
$ ./encr show-length 
Encrypted length: 256 (Actual length: 48) 

を取得また、./encr | wc | awk '{print $3;}'私が述べたWhereeverサイズ

を取得するには「正しい」それは私がRSA_public_encryptの私の使い方で間違ってやっていることは何

$ ./encr | openssl rsautl -decrypt -inkey private.pem 
RSA operation error 
140735156518992:error:0407109F:rsa routines:RSA_padding_check_PKCS1_type_2:pkcs decoding error:rsa_pk1.c:273: 
140735156518992:error:04065072:rsa routines:RSA_EAY_PRIVATE_DECRYPT:padding check failed:rsa_eay.c:602: 
$ ./encr | openssl rsautl -decrypt -inkey private.pem <---------------------------------- CORRECTLY PADDED 
plain text$ ./encr | openssl rsautl -decrypt -inkey private.pem 
RSA operation error 
140735156518992:error:0407109F:rsa routines:RSA_padding_check_PKCS1_type_2:pkcs decoding error:rsa_pk1.c:273: 
140735156518992:error:04065072:rsa routines:RSA_EAY_PRIVATE_DECRYPT:padding check failed:rsa_eay.c:602: 
$ ./encr | openssl rsautl -decrypt -inkey private.pem <---------------------------------- CORRECTLY PADDED 
plain text$ ./encr | openssl rsautl -decrypt -inkey private.pem <---------------------------------- CORRECTLY PADDED 
plain text$ ./encr | openssl rsautl -decrypt -inkey private.pem 
RSA operation error 
140735156518992:error:0407109F:rsa routines:RSA_padding_check_PKCS1_type_2:pkcs decoding error:rsa_pk1.c:273: 
140735156518992:error:04065072:rsa routines:RSA_EAY_PRIVATE_DECRYPT:padding check failed:rsa_eay.c:602: 

である私は(ここではサンプルがある)エラーが出るそうでない場合は罰金解読のだろうか? Cでは

+0

注:これはhttp://stackoverflow.com/questions/36267124/openssl-variable-length-result-for-rsa-encryption-c-programmingに似ていますが、その質問には適切な答えがありません。適切な意味では、何が起こっているのかを説明していません。 – mkhan

+2

暗号プリミティブを扱うときは、常にそれらがバイトを処理すると仮定します...それらはバイトを取ります...返されるバイト...なぜこれについて言及しますか?あなたは出力を文字列として扱います... strlen()は最初の0x00を返します...他のすべての文字列関数を実行します... – DarkSquirrel42

答えて

2

/C++ char*unsigned char*は、「文字列」または「いくつかのバイト」を意味するか、そしてそれがunsigned char*かかわらず、通常は「いくつかのバイトを」、意味(あるかを知るために、開発者次第ですが「符号なし」手がかり)。

RSAは、ほぼすべてのコンピュータ設計の暗号化ルーチンと同様に、バイト単位で動作します。時には入力バイトはテキストですが、出力バイトはほとんど常にありません。

40ビットのRSAキーをお持ちでしたら、答えは21 74 65 78 74です。その場所へのポインタ上のstrlenは、少なくとも5のいくつかの番号を返します。正確に5を返した場合は、運が良かったことを意味し、メモリの次のセグメントはすでに0x00として割り当てられています。この幸運なケースでは、ポインタをprintf(%s)して!textを発行します。

0x00である第2のバイトはstrlen「は、文字列の末尾を」どのように解釈するかであるので、それは同じように可能性が1ようになるstrlen25 00 F2 1B D5を生産している可能性があります。

出力をテキストにする必要がある場合は、テキスト形式に変換する必要があります。短い値の場合、16進数は一般的な方法ですが、RSA-2048は256バイトの答えを生成します。これは512桁の16進文字で、Base64では344しかないため、Base64エンコーディングがこのような状況で使用される傾向があります。

+0

私はあまりにも怠け者であることを書いてくれてありがとう... – DarkSquirrel42

+1

プログラム的に答えは出ていませんが、多くの概念を明確にしているので、これよりも優れていると思います。感謝 – mkhan