2017-01-20 5 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

언제 암호화 원시 처리, allways 그들이 바이트를 처리하는 가정 ... 그들은 바이트를 ... 다시 바이트를 줘 ... 왜 내가 이것을 언급합니까? 당신은 출력을 문자열로 취급합니다 ... strlen()은 처음 0x00에서 다시 찌를 것입니다 ... 그래서 다른 모든 문자열 함수를 수행하십시오 ... – DarkSquirrel42

답변

2

/C++ char*unsigned char*은 "문자열"또는 "일부 바이트를"을 의미 할 수 있습니다, 그것은 unsigned char*하지만 일반적으로 "일부 바이트"를 의미하는 (어떤 알고 개발자에게 달려되는 "부호" 실마리).

RSA는 거의 모든 컴퓨터 설계 암호화 루틴과 마찬가지로 바이트로 작동합니다. 때로는 입력 바이트가 텍스트이지만 출력 바이트는 거의 항상 없습니다.

40 비트 RSA 키를 가지고 있다면 대답은 21 74 65 78 74입니다. 해당 위치에 대한 포인터의 strlen은 ...이상의 숫자를 반환합니다. 정확히 5를 반환하면 운이 좋았고 메모리의 다음 세그먼트는 이미 0x00으로 지정되었음을 의미합니다. 그리고이 행운의 경우에 우리는 포인터를 printf (% s) 할 수 있고 !text을 방출 할 것입니다.

그냥 아마로 생산 수 25 00 F2 1B D5

, 어떤 1strlen 0x00되는 두 번째 바이트 방법 strlen 해석 "문자열의 끝"이기 때문에 것입니다.

출력이 텍스트 인 경우 텍스트 형식으로 변환해야합니다. 짧은 값에 대한 일반적인 방법은 16 진수이지만 RSA-2048은 256 바이트 응답을 생성합니다. 이는 512 개의 16 진수 문자이거나 Base64에서는 344 일 뿐이므로이 상황에서 Base64 인코딩이 사용되는 경향이 있습니다.

+0

내가 너무 게으른 것을 쓰는 것에 감사드립니다 ... – DarkSquirrel42

+1

프로그래밍 방식으로 답변을주지는 않지만 많은 개념을 명확히 해 주므로이 방법보다 낫다고 생각합니다. 감사 – mkhan