Sto cercando di capire come utilizzare la crittografia a chiave pubblica utilizzando l'implementazione openssl di rsa in C++. Puoi aiutare? Finora questi sono i miei pensieri (si prega di fare corretta se necessario)Puoi aiutarmi a capire meglio la crittografia a chiave pubblica openssl con rsa.h in C++?
- Alice è collegato a Bob su una rete
- Alice e Bob vogliono comunicazioni sicure
- Alice genera una coppia di chiavi pubblica/privata e invia pubblico chiave per Bob
- Bob riceve la chiave pubblica e crittografa una chiave cifra simmetrica generata in modo casuale (ad esempio, Blowfish) con la chiave pubblica e invia il risultato ad Alice
- Alice decifra il testo cifrato con la chiave privata originariamente generato e ottiene il pesce palla simmetrica chiave
- Alice e Bob ora entrambi hanno una conoscenza della chiave simmetrica Blowfish e possono stabilire un canale di comunicazione sicuro
ora, ho guardato il/rsa.h rsa implementazione OpenSSL (dato che già hanno esperienza pratica con OpenSSL /blowfish.h), e vedo queste due funzioni:
int RSA_public_encrypt(int flen, unsigned char *from,
unsigned char *to, RSA *rsa, int padding);
int RSA_private_decrypt(int flen, unsigned char *from,
unsigned char *to, RSA *rsa, int padding);
Se Alice è quello di generare * rsa, come fa questo rendimento della coppia di chiavi RSA? C'è qualcosa come rsa_public e rsa_private che derivano da rsa? * Rsa contiene sia la chiave pubblica che quella privata e la funzione sopra descritta rimuove automaticamente la chiave necessaria a seconda che richieda la parte pubblica o privata? Se due unici * puntatori rsa essere generati in modo che in realtà, abbiamo la seguente:
int RSA_public_encrypt(int flen, unsigned char *from,
unsigned char *to, RSA *rsa_public, int padding);
int RSA_private_decrypt(int flen, unsigned char *from,
unsigned char *to, RSA *rsa_private, int padding);
In secondo luogo, in quale formato dovrebbe il * chiave pubblica RSA da inviare a Bob? Deve essere reinterpretato in un array di caratteri e quindi inviato in modo standard? Ho sentito qualcosa sui certificati: hanno qualcosa a che fare con questo?
Ci scusiamo per tutte le domande, Auguri, Ben.
EDIT: Coe Attualmente sto impiegando:
/*
* theEncryptor.cpp
*
*
* Created by ben on 14/01/2010.
* Copyright 2010 __MyCompanyName__. All rights reserved.
*
*/
#include "theEncryptor.h"
#include <iostream>
#include <sys/socket.h>
#include <sstream>
theEncryptor::theEncryptor()
{
}
void
theEncryptor::blowfish(unsigned char *data, int data_len, unsigned char* key, int enc)
{
// hash the key first!
unsigned char obuf[20];
bzero(obuf,20);
SHA1((const unsigned char*)key, 64, obuf);
BF_KEY bfkey;
int keySize = 16;//strlen((char*)key);
BF_set_key(&bfkey, keySize, obuf);
unsigned char ivec[16];
memset(ivec, 0, 16);
unsigned char* out=(unsigned char*) malloc(data_len);
bzero(out,data_len);
int num = 0;
BF_cfb64_encrypt(data, out, data_len, &bfkey, ivec, &num, enc);
//for(int i = 0;i<data_len;i++)data[i]=out[i];
memcpy(data, out, data_len);
free(out);
}
void
theEncryptor::generateRSAKeyPair(int bits)
{
rsa = RSA_generate_key(bits, 65537, NULL, NULL);
}
int
theEncryptor::publicEncrypt(unsigned char* data, unsigned char* dataEncrypted,int dataLen)
{
return RSA_public_encrypt(dataLen, data, dataEncrypted, rsa, RSA_PKCS1_OAEP_PADDING);
}
int
theEncryptor::privateDecrypt(unsigned char* dataEncrypted,
unsigned char* dataDecrypted)
{
return RSA_private_decrypt(RSA_size(rsa), dataEncrypted,
dataDecrypted, rsa, RSA_PKCS1_OAEP_PADDING);
}
void
theEncryptor::receivePublicKeyAndSetRSA(int sock, int bits)
{
int max_hex_size = (bits/4) + 1;
char keybufA[max_hex_size];
bzero(keybufA,max_hex_size);
char keybufB[max_hex_size];
bzero(keybufB,max_hex_size);
int n = recv(sock,keybufA,max_hex_size,0);
n = send(sock,"OK",2,0);
n = recv(sock,keybufB,max_hex_size,0);
n = send(sock,"OK",2,0);
rsa = RSA_new();
BN_hex2bn(&rsa->n, keybufA);
BN_hex2bn(&rsa->e, keybufB);
}
void
theEncryptor::transmitPublicKey(int sock, int bits)
{
const int max_hex_size = (bits/4) + 1;
long size = max_hex_size;
char keyBufferA[size];
char keyBufferB[size];
bzero(keyBufferA,size);
bzero(keyBufferB,size);
sprintf(keyBufferA,"%s\r\n",BN_bn2hex(rsa->n));
sprintf(keyBufferB,"%s\r\n",BN_bn2hex(rsa->e));
int n = send(sock,keyBufferA,size,0);
char recBuf[2];
n = recv(sock,recBuf,2,0);
n = send(sock,keyBufferB,size,0);
n = recv(sock,recBuf,2,0);
}
void
theEncryptor::generateRandomBlowfishKey(unsigned char* key, int bytes)
{
/*
srand((unsigned)time(NULL));
std::ostringstream stm;
for(int i = 0;i<bytes;i++){
int randomValue = 65 + rand()% 26;
stm << (char)((int)randomValue);
}
std::string str(stm.str());
const char* strs = str.c_str();
for(int i = 0;bytes;i++)key[i]=strs[i];
*/
int n = RAND_bytes(key, bytes);
if(n==0)std::cout<<"Warning key was generated with bad entropy. You should not consider communication to be secure"<<std::endl;
}
theEncryptor::~theEncryptor(){}
Si noti che lo schema proposto è vulnerabile a questo: 3a) Eve intercetta la chiave pubblica di Alice. 3b) Eve genera una coppia di chiavi pubblica/privata e invia la chiave pubblica a Bob, affermando di essere Alice. 4a) Eve intercetta la chiave simmetrica crittografata e la decrittografa con la sua chiave privata. 4b) Eve ricodifica la chiave simmetrica con la chiave pubblica di Alice e la invia ad Alice, dichiarando di essere Bob. Alice, Bob ed Eve (a insaputa di Alice e Bob) ora condividono tutti la stessa chiave simmetrica. Eve è libero di decodificare tutti i dati successivi inviati tra Alice e Bob. – caf
Dio, hai assolutamente ragione. Grazie gentilmente per avermelo fatto notare :-) –
Ho aggiornato la mia risposta mostrando come usare le funzioni 'EVP_Seal *()' - sono abbastanza buone una volta che hai un esempio funzionante da guardare, è la documentazione che è un po ' carente. – caf