- 生成 DH 密鑰對
//! \param prime. DH 的 prime.
//! \param gen. DH 的 gen.
//! \param dh. 傳回資料.
//! \return. 成功與否.
int generate_dh_key(const char *prime, const char *gen, DH *dh)
{
BIGNUM *p = BN_new();
BIGNUM *g = BN_new();
BN_hex2bn(&p, prime);
BN_hex2bn(&g, gen);
DH_set0_pqg(dh, p, NULL, g);
/* generate key */
if (1 != DH_generate_key(dh)) {
perror("DH_generate_key failed!");
return -1;
}
return 0;
}
- 生成 DH 共享密鑰,此處有坑:使用 openssl DH_compute_key() 函數計算 DH 密鑰長度不對的問題
//! \param dh. DH,其中有本端的公鑰和私鑰.
//! \param peer_pub_key. 對端 DH 公鑰.
//! \param peer_pub_key_len. 對端 DH 公鑰長度.
//! \param shared_key. 輸出 DH 共享密鑰.
//! \return. DH 共享密鑰長度.
int gene_shared_key(DH *dh, uint8_t *peer_pub_key,
uint16_t peer_pub_key_len, unsigned char *shared_key) {
BIGNUM *p_pub_key = BN_bin2bn(peer_pub_key, peer_pub_key_len, NULL);
/* computer shared_dh_secret */
int shared_key_len = DH_compute_key_padded(shared_key, p_pub_key, dh);
if(-1 == shared_key_len) {
perror("DH_compute_key_padded failed!");
return -1;
}
return shared_key_len;
}
- 中間人攻擊
- 截獲雙方發送的 DH 公共值
- 修改為自己的公共值發送給雙方
- 使用兩端的公共值同自身的 dh 分别生成中間人到用戶端以及中間人到伺服器的共享密鑰
- 實作中間人