如何使用Crypto ++进行DH密钥交换(CryptoPP :: DH :: Agree返回false)

时间:2017-09-05 10:25:06

标签: crypto++ diffie-hellman

我正在尝试使用Crypto ++来执行Diffie-Hellman密钥交换。我写了一个简单的程序来检查这是否有效。你可以猜到,它不是。

该程序是基于wiki文章编写的:https://www.cryptopp.com/wiki/Diffie-Hellman它生成公钥和私钥,然后将它们用于cal函数CryptoPP::DH::Agree。当我在维基上使用同一对双键时,它正在工作。但这并没有多少实际意义。但是,当我尝试使用不同的密钥时,CryptoPP::DH::Agree会返回false

我怀疑我做错了什么,但我不知道是什么。

#include <crypto++/cryptlib.h>
#include <crypto++/dh.h>
#include <cryptopp/dh2.h>
#include <crypto++/osrng.h>
#include <crypto++/integer.h>
#include <crypto++/nbtheory.h>
#include <iostream>


static CryptoPP::AutoSeededRandomPool rnd;
static CryptoPP::DH dhA, dhB;
static CryptoPP::SecByteBlock privKeyA, pubKeyA, privKeyB, pubKeyB;


static void createDomainParameters(CryptoPP::DH &dh)
{
    CryptoPP::PrimeAndGenerator pg;
    pg.Generate(1, rnd, 512, 511);
    const CryptoPP::Integer p = pg.Prime();
    const CryptoPP::Integer q = pg.SubPrime();
    const CryptoPP::Integer g = pg.Generator();

    std::cout << "P: " << p << '\n';
    std::cout << "Q: " << q << '\n';
    std::cout << "G: " << g << '\n';

    dh = CryptoPP::DH(p, q, g);
}

static void createAsymetricKey(const CryptoPP::DH &dh, CryptoPP::SecByteBlock &privKey, CryptoPP::SecByteBlock &pubKey)
{
    privKey = CryptoPP::SecByteBlock(dh.PrivateKeyLength());
    pubKey = CryptoPP::SecByteBlock(dh.PublicKeyLength());
    dh.GenerateKeyPair(rnd, privKey, pubKey);

    CryptoPP::Integer a, b;

    a.Decode(privKey.BytePtr(), privKey.SizeInBytes());
    std::cout << "privKey: " << a << std::endl;

    b.Decode(pubKey.BytePtr(), pubKey.SizeInBytes());
    std::cout << "pubKey:  " << b << std::endl;
}

static void createSymetricKey(const CryptoPP::DH &dh, const CryptoPP::SecByteBlock &privKey, const CryptoPP::SecByteBlock &pubKey)
{
    CryptoPP::SecByteBlock shared(dh.AgreedValueLength());
    if(!dh.Agree(shared, privKey, pubKey))
        throw std::runtime_error("Failed to reach shared secret");

    CryptoPP::Integer x;
    x.Decode(shared.BytePtr(), shared.SizeInBytes());
    std::cout << "shared: " << x << std::endl;
}

int main()
{
    std::cout << std::hex;

    createDomainParameters(dhA);
    std::cout << std::endl;
    createDomainParameters(dhB);

    std::cout << "\n------------------------------\n" << std::endl;
    createAsymetricKey(dhA, privKeyA, pubKeyA);
    std::cout << std::endl;
    createAsymetricKey(dhB, privKeyB, pubKeyB);

    if(dhA.AgreedValueLength() != dhB.AgreedValueLength())
        throw std::runtime_error("Shared secret size mismatch");

    std::cout << "\n------------------------------\n" << std::endl;
    createSymetricKey(dhA, privKeyA, pubKeyB);
    std::cout << std::endl;
    createSymetricKey(dhB, privKeyB, pubKeyA);

    return 0;
}

当您更改createSymetricKey的来电时,它会使用来自同一对的密钥,它可以正常工作。

createSymetricKey(dhA, privKeyA, pubKeyA);
std::cout << std::endl;
createSymetricKey(dhB, privKeyB, pubKeyB);

AFAIK这没有任何意义。使用CryptoPP::DH::Agree的正确方法是什么?

0 个答案:

没有答案