ECIES Public 密钥序列化
ECIES Public Key serialization
我正在编写 Client/Server 加密程序并想发送 ECIES public 密钥。为此,我必须将 public 键序列化到文件,将文件读取到字节数组,然后发送这个字节数组。另一方面:接收字节数组,将其写入文件,反序列化文件中的 public 键。所以,我写了一些测试项目,尝试将它与伟大的系统分开,并且(当所有这个模块都能成功运行时)只需将它插入我的项目中。本项目代码为:
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
为什么?
我删除了对 RSA 的引用,因为看起来您正在使用 ECIES。干得好。
terminate called after throwing an instance of '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 字符串对其进行操作。
这应该 return 一个 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;
可以在 Read whole ASCII file into 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
.
我正在编写 Client/Server 加密程序并想发送 ECIES public 密钥。为此,我必须将 public 键序列化到文件,将文件读取到字节数组,然后发送这个字节数组。另一方面:接收字节数组,将其写入文件,反序列化文件中的 public 键。所以,我写了一些测试项目,尝试将它与伟大的系统分开,并且(当所有这个模块都能成功运行时)只需将它插入我的项目中。本项目代码为:
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
为什么?
我删除了对 RSA 的引用,因为看起来您正在使用 ECIES。干得好。
terminate called after throwing an instance of '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 字符串对其进行操作。
这应该 return 一个 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;
可以在 Read whole ASCII file into 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
.