2017-01-20 3 views
2

Ich habe Beispielprogramm (von Online-Proben genommen), die RSA-Verschlüsselung erzeugt.RSA Variable verschlüsselt Länge

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

und ein privater Schlüssel ist:

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

Als ich es bauen

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

und es mehrmals laufen, ich Variable "Tatsächliche Länge"

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

erhalten Sie können auch ./encr | wc | awk '{print $3;}' tun

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

Was ist das, was ich falsch mache in meiner Nutzung von RSA_public_encrypt zu bekommen Größen

Überall dort, wo ich „richtig“ erwähnt wird es entschlüsseln feine sonst (Probe hier sind) bekomme ich Fehler? Sein

+0

Hinweis: Dies ist ähnlich wie http://stackoverflow.com/questions/36267124/openssl-variable-length-result-for-rsa-encryption-c-programming aber diese Frage hat keine passende Antwort. Mit passender Bedeutung meine ich nicht, was passiert. – mkhan

+2

im Umgang mit kryptografischen Primitiven gehen wir immer davon aus, dass sie mit Bytes umgehen ... sie nehmen Bytes ... die zurückgebenden Bytes ... warum erwähne ich das? ... Sie behandeln die Ausgabe als String strlen() wird dem Rücken an der ersten 0x00 erstechen ... so alle anderen String-Funktionen tun ... – DarkSquirrel42

Antwort

2

In C/C++ char* und unsigned char* kann entweder bedeuten, „eine Zeichenkette“ oder „einige Bytes“, und es liegt an den Entwickler zu wissen, was was ist (obwohl unsigned char* in der Regel bedeutet „einige Bytes“, die „unsigned“ der Hinweis).

RSA, wie fast alle Computer entworfene Verschlüsselungsroutinen arbeitet auf Byte. Manchmal sind die Eingabebytes Text, aber die Ausgabebytes sind fast immer nicht.

Wenn Sie ein 40-Bit-RSA-Schlüssel hatte, könnte es als Antwort 21 74 65 78 74 produzieren. strlen auf einen Zeiger auf diese Position wird zurück ... eine Zahl, die mindestens 5 ist. Wenn es genau 5 zurückgibt, bedeutet das, dass wir Glück hatten und das nächste Speichersegment wurde bereits als 0x00 zugewiesen. Und in diesem glücklichen Fall könnten wir den Zeiger (% s) drucken und er wird !text ausgeben.

Es ist wahrscheinlich 25 00 F2 1B D5 produziert wie könnte, das wird strlen als 1 weil das zweite Byte 0x00 ist, wie strlen interpretiert „Ende der Kette“ zu sein.

Wenn Sie Ihren Ausgang benötigen Text zu sein, müssen Sie es in eine Textform konvertieren. Hexadezimal ist eine häufige Methode für kurze Werte, aber RSA-2048 erzeugt eine 256-Byte-Antwort. Das wären 512 Hexadezimalzeichen, oder in Base64 wären es nur 344, weshalb in diesen Situationen die Base64-Kodierung verwendet wird.

+0

Danke für das Schreiben, was ich war zu faul ... – DarkSquirrel42

+1

Obwohl es gibt keine programmatische Antwort, aber ich glaube, das ist besser als das, da es viele Konzepte verdeutlicht. Geschätzt – mkhan