Сериализация открытого ключа ECIES

Я пишу зашифрованную клиент / серверную программу и хочу отправить открытый ключ ECIES. Для этого я должен сериализовать открытый ключ в файл, прочитать файл в байтовый массив, отправить этот байтовый массив. С другой стороны: получить байтовый массив, записать его в файл, десериализовать открытый ключ из файла. Итак, я написал тестовый проект, для того, чтобы попробовать сделать это отдельно от отличной системы, и (когда весь этот модуль будет работать успешно) просто вставить его в мой проект. Код этого проекта:

class EncoderRSA
{
public:
EncoderRSA();
void keyGeneration();
std::string encrypt(std::string plainText);
std::string decrypt(std::string cypher);
void setRsaPublicKey(char *publicKeyInCharArray);
char *getRsaPublicKey();
private:
AutoSeededRandomPool prng;  // Pseudo Random Number Generator
ECIES<ECP>::Decryptor rsaDecryptor;
ECIES<ECP>::Encryptor rsaEncryptor;
};

И, строго говоря, простые (для проблемных) методы:

char *EncoderRSA::getRsaPublicKey() {
std::string file = "publicKey.txt";

//Save public key in file
FileSink sink(file.c_str());
this->rsaEncryptor.GetPublicKey().Save(sink);

//Read file with public key into the buffer
std::ifstream infile (file.c_str(),std::ifstream::binary);

if (!infile.is_open()) {
std::cout << "Can't open file to write" << std::endl;
exit(1);
}

// get size of file
infile.seekg (0,infile.end);
long size = infile.tellg();
infile.seekg (0);

// allocate memory for file content
char* buffer = new char[size];
infile.read (buffer,size);
infile.close();

return buffer;
}

void EncoderRSA::setRsaPublicKey(char *publicKeyInCharArray) {
std::string file = "publicKey.txt";

int size = strlen(publicKeyInCharArray);

//Write received public key in file
std::ofstream outfile (file.c_str(),std::ofstream::binary);

if (!outfile.is_open()) {
std::cout << "Can't open file to write" << std::endl;
exit(1);
}

outfile.write (publicKeyInCharArray,size);
outfile.close();

// release dynamically-allocated memory
delete[] publicKeyInCharArray;

//Load public key from file
FileSource source(file.c_str(), true);
this->rsaEncryptor.AccessPublicKey().Load(source);
}

Кодекс main.cpp:

int main() {
char *buffer = keysEncoder.getRsaPublicKey();
cout << "buffer: " << buffer << endl;
//...
//send buffer
//receive buffer from other side
//..
keysEncoder.setRsaPublicKey(buffer);

string decoded = keysEncoder.decrypt(cypher);
cout << "decoded: " << decoded << endl;

return 0;
}

Но он вылетел с ошибкой:

terminate called after throwing an instance of 'CryptoPP::BERDecoderErr'
wait(): BER decode error
Aborted (core dumped)

Process returned 134 (0x86)    execution time: 2.891

Зачем?

4

Решение

Я удалил ссылки на RSA, так как похоже, что вы используете ECIES. Хорошая работа на этом.


прекращение вызова после создания экземпляра CryptoPP :: BERDecoderErr

Очевидно, вам нужно настроить try / catch:

try
{
...
}
catch(const BERDecoderErr& ex)
{
cerr << ex.what() << endl;
}

char *Encoder::getPublicKey() {
...
char* buffer = ...
return buffer;
}

Кодировка ASN.1 / DER, скорее всего, будет иметь встроенный NULL, поэтому вы не можете работать с ней, используя традиционные C-строки.

Это, вероятно, должно вернуть std::string поэтому вывод не усекается с первым символом NULL:

// get size of file
infile.seekg (0,infile.end);
long size = infile.tellg();
infile.seekg (0);

// allocate memory for file content
string buffer(size, '0');
infile.read (&buffer[0], size);
infile.close();

return buffer;

Другой способ выполнить чтение из файла можно найти по адресу Прочитать весь файл ASCII в C ++ std :: string:

std::ifstream infile (file.c_str(), std::ifstream::binary);
std::string buffer((std::istreambuf_iterator<char>(infile)),
std::istreambuf_iterator<char>());

Другой способ заключается в обеспечении NULLне присутствуют в выводе и вводе:

string Encoder::getPublicKey() {
string encodedKey;
HexEncoder sink(new StringSink(encodedKey));
Encryptor.GetPublicKey().Save(sink);
return encodedKey;
}

А также:

void Encoder::setPublicKey(const string& encodedKey) {
StringSource source(encodedKey, new HexDecoder());
Encryptor.AccessPublicKey().Load(source);
}

Код выше использует StringSource а также StringSink, так что он работает на вещи в памяти. если ты действительно хотите промежуточные файлы на диске, затем используйте FileSource а также FileSink,

1

Другие решения


По вопросам рекламы [email protected]