Я пытаюсь использовать шифрование открытого ключа, используя реализацию rsa openssl в C++. Вы можете помочь? До сих пор это мои мысли (пожалуйста, при необходимости исправить)Можете ли вы помочь мне разобраться с открытым ключом opensl с помощью rsa.h в C++?
- Алиса подключается к Бобу через сеть
- Алиса и Боб хотят безопасной связи
- Алиса генерирует пару открытый/закрытый ключ и посылает общественности ключ к Бобу
- Боб получает открытый ключ и шифрует случайно сгенерированный симметричный Cypher ключ (например, Blowfish) с помощью открытого ключа и посылает результат Алисе
- Алиса расшифровывает шифрованную с первоначально сгенерированным секретным ключом и получает симметричный Blowfish ключ
- Алиса и Боб теперь оба имеют знание симметричной Blowfish ключа и могут установить безопасный канал связи
Теперь я смотрел на OpenSSL/реализации rsa.h RSA (поскольку у меня уже есть практический опыт работы с OpenSSL /blowfish.h), и я вижу эти две функции:
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);
Если Алиса генерировать * ПДС, как же этот выход пары ключей RSA? Есть что-то вроде rsa_public и rsa_private, которые получены из rsa? Имеет ли * rsa как открытый, так и закрытый ключ, и указанная выше функция автоматически удаляет необходимый ключ в зависимости от того, нужна ли ему государственная или частная часть? Если два уникальных * ЗГА указателей генерироваться так, что на самом деле, мы имеем следующее:
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);
Во-вторых, в каком формате если * RSA открытый ключ будет отправлен Боб? Должно ли оно быть переинтерпретировано в массив символов, а затем отправлено стандартным способом? Я слышал что-то о сертификатах - они что-то с этим связаны?
Извините за все вопросы, Наилучшие пожелания, Бен.
EDIT: Коу я в настоящее время занято:
/*
* 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(){}
Обратите внимание, что ваша предлагаемая схема уязвима для этого: 3a) Ева перехватывает открытый ключ Алисы. 3b) Eve генерирует пару открытых/закрытых ключей и отправляет открытый ключ Бобу, заявляя, что является Алисой. 4a) Ева перехватывает зашифрованный симметричный ключ и расшифровывает его своим личным ключом. 4b) Eve повторно шифрует симметричный ключ открытым ключом Алисы и отправляет его Алисе, заявляя, что она Боб. Алиса, Боб и Ева (неизвестные Алисе и Бобу) теперь все имеют одинаковый симметричный ключ. Ева может расшифровать все последующие данные, отправленные Алисой и Бобом. – caf
Боже, ты совершенно прав. Благодарим за указание :-) –
Я обновил свой ответ, рассказывая, как использовать функции 'EVP_Seal *()', они очень хороши, как только у вас есть рабочий пример, чтобы посмотреть, это небольшая документация не хватает. – caf