2017-01-20 6 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;}' чтобы получить размеры

Где бы я говорил «правильно» он будет расшифровывать штраф в противном случае я получаю ошибки (здесь образец)

$ ./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: 

Что это такое, что я делаю неправильно в моем использовании RSA_public_encrypt?

+0

ПРИМЕЧАНИЕ. Это похоже на http://stackoverflow.com/questions/36267124/openssl-variable-length-result-for-rsa-encryption-c-programming, но этот вопрос не имеет подходящего ответа. Под подходящим я имею в виду, не объясняет, что происходит. – mkhan

+2

при работе с криптографическими примитивами, все они предполагают, что они обрабатывают байты ... они берут байты ... возвращают байты ... почему я упоминаю об этом? вы обрабатываете вывод как строку ... strlen() будет ударять вас назад в первом 0x00 ... так что все остальные строковые функции ... – DarkSquirrel42

ответ

2

В C/C++ char* и unsigned char* может означать либо «строку» или «несколько байт», и это до разработчика, чтобы узнать, что есть что (хотя unsigned char* обычно означает «несколько байт», то «без знака» быть ключ).

RSA, как и почти все компьютерные криптографические процедуры, работает с байтами. Иногда входные байты представляют собой текст, но байты вывода почти всегда отсутствуют.

Если у вас есть 40-разрядный ключ RSA, он может быть получен как ответ 21 74 65 78 74. strlen на указатель на это место вернется ... некоторое число, которое составляет не менее 5. Если он возвращает ровно 5, это означает, что нам повезло, и следующий сегмент памяти уже был назначен как 0x00. И в этом счастливом случае мы могли бы напечатать f (% s) указатель, и он испустит !text.

Это могло быть столь же вероятно, произвел 25 00 F2 1B D5, который будет strlen как 1, потому что второй байт является 0x00 является как strlen трактует «конец строки».

Если вам нужен ваш текст для вывода текста, вам нужно будет преобразовать его в текстовую форму. Шестнадцатеричный - это общий способ для коротких значений, но RSA-2048 дает 256-байтовый ответ. Это будет 512 шестнадцатеричных символов, или в Base64 это будет только 344, поэтому кодирование Base64 имеет тенденцию использоваться в этих ситуациях.

+0

спасибо, что написал, что я слишком ленив для ... – DarkSquirrel42

+1

Хотя это не дает ответа программно, но я считаю, что это лучше, чем это, поскольку оно разъясняет много понятий. Оценил – mkhan

Смежные вопросы