技术

Diffie-Hellman算法

2017-10-20  本文已影响0人  flycloud_hz

0x0 Diffie-Hellman介绍

Diffie-Hellman简称DH算法,用于密钥交换,两端使用相同p,g参数,生成一对公私钥,一端私钥和另一端公钥生成一个key(prime_len参数为key的字节 * 8,比如key需要24个字节,那么prime_len为192),key可以作为AES密钥做加解密。

0x1 代码实现

生成的key为24字节,可以作为AES 192bits key

h文件

class DHCrypt {
public:
    DHCrypt();
    ~DHCrypt();

public:
    bool Init();
    std::string getP();
    std::string getG();
    std::string getPubKey();
    bool ComputeKey(const std::string& input, std::string& output);

private:
    bool initialized_;
    DH* dh_;
    std::string param_p_;
    std::string param_g_;
    std::string public_key_;
};

cpp文件

DHCrypt::DHCrypt()
: initialized_(false), dh_(NULL){

}

DHCrypt::~DHCrypt() {
    if (dh_) {
        DH_free(dh_);
        dh_ = NULL;
    }
}

bool DHCrypt::Init() {
    if (initialized_) {
        LOGE("init already done");
        return true;
    }
    dh_ = DH_new();
    if (dh_&& DH_generate_parameters_ex(dh_, 192, DH_GENERATOR_2, NULL) != 0) {
        const BIGNUM* p = NULL;
        const BIGNUM* g = NULL;
        DH_get0_pqg(dh_, &p, NULL, &g);
        if (p) {
            int len = BN_num_bytes(p);
            unsigned char* buf = new unsigned char[len];
            int l = BN_bn2bin(p, buf);
            param_p_ = std::string((char*)buf, l);
            delete[] buf;
        }
        if (g) {
            int len = BN_num_bytes(g);
            unsigned char* buf = new unsigned char[len];
            int l = BN_bn2bin(g, buf);
            param_g_ = std::string((char*)buf, l);
            delete[] buf;
        }
        if (DH_generate_key(dh_) != 0) {
            const BIGNUM* pub_key = NULL;
            const BIGNUM* pri_key = NULL;
            DH_get0_key(dh_, &pub_key, &pri_key);
            if (pub_key) {

                int len = BN_num_bytes(pub_key);
                unsigned char* buf = new unsigned char[len];
                int l = BN_bn2bin(pub_key, buf);
                public_key_ = std::string((char*)buf, l);
                delete[] buf;
            }
        }
        initialized_ = true;
    } else {
        LOGE("DH_generate_parameters_ex error");
    }

    return initialized_;
}

std::string DHCrypt::getP() {
    return param_p_;
}

std::string DHCrypt::getG() {
    return param_g_;
}

std::string DHCrypt::getPubKey() {
    return public_key_;
}

bool DHCrypt::ComputeKey(const std::string& input, std::string& output) {
    if (!initialized_) {
        LOGE("init not done");
        return false;
    }
    bool result = false;
    if (dh_) {
        int size = DH_size(dh_);
        unsigned char* buf = (unsigned char*)OPENSSL_malloc(size);
        if (buf) {
            BIGNUM* bn = BN_bin2bn((const unsigned char*)input.c_str(), input.length(), NULL);
            if (bn) {
                int len = DH_compute_key(buf, bn, dh_);
                if (len > 0) {
                    output = std::string((char*)buf, len);
                    result = true;
                } else {
                    LOGE("DH_compute_key error");
                }
                BN_free(bn);
            } else {
                LOGE("BN_bin2bn error");
            }
            OPENSSL_free(buf);
        }
    }

    return result;
}
上一篇下一篇

猜你喜欢

热点阅读