c++ - ECIES公钥序列化

标签 c++ encryption crypto++ 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

为什么?

最佳答案

我删除了对 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 字符串对其进行操作。

这可能会返回一个 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);
}

上面的代码使用了 StringSourceStringSink,因此它对内存中的内容进行操作。如果您真的想要磁盘上的中间文件,请使用FileSourceFileSink

关于c++ - ECIES公钥序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32665800/

相关文章:

Java cipher.doFinal() 写入额外的字节

android - 如何将 Crypto++ 与 Jni 或 NDK 一起用于 Android 应用程序

c++ - Qt C++ QException 问题 : debug error

python - 用于 C++ 和 Python 的轻量级密码学工具包

android - 支持的算法错误?

c++ - 由于 undefined reference ,无法链接到 Debian 上的 Crypto++

c++ - AES IV通过FileSource和FileSink进入文件

c++ - LIVE555 - 收到第一帧后设置 SPS 和 PPS

c++ - 对于开始游戏开发探索的新手,您推荐哪些游戏创意?

c++ - 是否自动返回局部变量 xvalues