在Crypto ++中从内存加载密钥

时间:2014-09-24 02:55:02

标签: c++ crypto++

我正在尝试将公共DLIES密钥保存到内存中,然后再次读取它,但我不断获得异常BER decode error。我使用ArraySinkArraySourcechar[64]缓冲区在两个CryptoPP::DLIES<>::PublicKey之间传输密钥。我甚至验证公钥是好的。我错过了什么?

以下是无效的完整示例。如何修改它以便正确加载密钥?

#include <iostream>
#include <gfpcrypt.h>
#include <filters.h>
#include <osrng.h>

int main() {
    try {
        CryptoPP::DefaultAutoSeededRNG rng;

        CryptoPP::DLIES<>::PrivateKey privateKey;
        privateKey.GenerateRandomWithKeySize(rng, 10);

        CryptoPP::DLIES<>::PublicKey publicKey;
        privateKey.MakePublicKey(publicKey);

        if (!publicKey.Validate(rng, 3)) {
            std::cout << "Something wrong with public key." << std::endl;
            return 1;
        }

        byte buf[64];
        CryptoPP::ArraySink sink(buf, 64);
        publicKey.Save(sink);

        CryptoPP::ArraySource source((const char *)buf, sink.TotalPutLength());
        CryptoPP::DLIES<>::PublicKey pk;
        pk.Load(source);
    } catch (CryptoPP::Exception &ex) {
        std::cout << ex.what() << std::endl;
        return 1;
    }

    return 0;
}

1 个答案:

答案 0 :(得分:1)

问题在于没有设置pumpAll=true构造函数的ArraySource第3个参数。添加后,它工作。另一个有效的解决方案是使用ByteQueue代替。为了完整起见,我在下面粘贴了两个工作示例。

ArraySource版本:

#include <iostream>
#include <gfpcrypt.h>
#include <filters.h>
#include <osrng.h>

int main() {
    try {
        CryptoPP::DefaultAutoSeededRNG rng;

        CryptoPP::DLIES<>::PrivateKey privateKey;
        privateKey.GenerateRandomWithKeySize(rng, 10);

        CryptoPP::DLIES<>::PublicKey publicKey;
        privateKey.MakePublicKey(publicKey);

        if (!publicKey.Validate(rng, 3)) {
            std::cout << "Something wrong with sent public key." << std::endl;
            return 1;
        }

        byte buf[64];
        CryptoPP::ArraySink sink(buf, 64);
        publicKey.Save(sink);

        CryptoPP::ArraySource source(buf, sink.TotalPutLength(), true);
        CryptoPP::DLIES<>::PublicKey pk;
        pk.Load(source);

        if (!pk.Validate(rng, 3)) {
            std::cout << "Something wrong with received public key." << std::endl;
            return 1;
        }
    } catch (CryptoPP::Exception &ex) {
        std::cout << ex.what() << std::endl;
        return 1;
    }

    return 0;
}

ByteQueue版本(我最终发现它更方便):

#include <iostream>
#include <gfpcrypt.h>
#include <filters.h>
#include <osrng.h>

int main() {
    try {
        CryptoPP::DefaultAutoSeededRNG rng;

        CryptoPP::DLIES<>::PrivateKey privateKey;
        privateKey.GenerateRandomWithKeySize(rng, 10);

        CryptoPP::DLIES<>::PublicKey publicKey;
        privateKey.MakePublicKey(publicKey);

        if (!publicKey.Validate(rng, 3)) {
            std::cout << "Something wrong with sent public key." << std::endl;
            return 1;
        }

        CryptoPP::ByteQueue queue;
        publicKey.Save(queue);
        CryptoPP::lword size = queue.TotalBytesRetrievable();

        byte buf[64];
        queue.Get(buf, size);

        CryptoPP::ByteQueue queue2;
        queue2.Put(buf, size);
        CryptoPP::DLIES<>::PublicKey pk;
        pk.Load(queue2);

        if (!pk.Validate(rng, 3)) {
            std::cout << "Something wrong with received public key." << std::endl;
            return 1;
        }
    } catch (CryptoPP::Exception &ex) {
        std::cout << ex.what() << std::endl;
        return 1;
    }

    return 0;
}