搬一下別人的解釋:
下面我們以Alice和Bob爲例敘述Diffie-Hellman密鑰交換的原理。
1,Diffie-Hellman交換過程中涉及到的所有參與者定義一個組,在這個組中定義一個大質數p,底數g。
2,Diffie-Hellman密鑰交換是一個兩部分的過程,Alice和Bob都需要一個私有的數字a,b。
下面是DH交換的過程圖:
本圖片來自wiki
下面我們進行一個實例
1.愛麗絲與鮑伯協定使用p=23以及g=5.
2.愛麗絲選擇一個祕密整數a=6, 計算A = g^a mod p併發送給鮑伯。
A = 5^6 mod 23 = 8.
3.鮑伯選擇一個祕密整數b=15, 計算B = g^b mod p併發送給愛麗絲。
B = 5^15 mod 23 = 19.
4.愛麗絲計算s = B a mod p
19^6 mod 23 = 2.
5.鮑伯計算s = A b mod p
8^15 mod 23 = 2.
ECDH密鑰交換:
ECDH:
ECC算法和DH結合使用,用於密鑰磋商,這個密鑰交換算法稱爲ECDH。交換雙方可以在不共享任何祕密的情況下協商出一個密鑰。ECC是建立在基於橢圓曲線的離散對數問題上的密碼體制,給定橢圓曲線上的一個點P,一個整數k,求解Q=kP很容易;給定一個點P、Q,知道Q=kP,求整數k確是一個難題。ECDH即建立在此數學難題之上。密鑰磋商過程:
假設密鑰交換雙方爲Alice、Bob,其有共享曲線參數(橢圓曲線E、階N、基點G)。
1) Alice生成隨機整數a,計算A=a*G。 #生成Alice公鑰
2) Bob生成隨機整數b,計算B=b*G。 #生產Bob公鑰
3) Alice將A傳遞給Bob。A的傳遞可以公開,即攻擊者可以獲取A。
由於橢圓曲線的離散對數問題是難題,所以攻擊者不可以通過A、G計算出a。
4) Bob將B傳遞給Alice。同理,B的傳遞可以公開。
5) Bob收到Alice傳遞的A,計算Q =b*A#Bob通過自己的私鑰和Alice的公鑰得到對稱密鑰Q
6) Alice收到Bob傳遞的B,計算Q`=a*B#Alice通過自己的私鑰和Bob的公鑰得到對稱密鑰Q'
Alice、Bob雙方即得Q=b*A=b*(a*G)=(b*a)*G=(a*b)*G=a*(b*G)=a*B=Q' (交換律和結合律),即雙方得到一致的密鑰Q。
目前Openssl裏面的ECC算法的套件支持是ECDSA/ECDH。在國密的SSL套件中,可以使用ECDSA/ECC(密鑰加密傳輸),ECDSA/ECDH(密鑰磋商)兩種套件
作者:介和
鏈接:https://www.jianshu.com/p/b26cd2bfdc28
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯繫作者獲得授權並註明出處。
測試代碼:
#include "stdafx.h"
#include <string.h>
#include <stdio.h>
#include <openssl/ec.h>
#include <openssl/ecdh.h>
#include <openssl/ecdsa.h>
#include <openssl/objects.h>
#include <openssl/err.h>
#define ECDH_SIZE 256
void handleErrors()
{
printf("Error occurred.\n");
}
void disp(const char *str, const void *pbuf, const int size)
{
int i=0;
if (str !=NULL)
{
printf("%s:\n", str);
}
if (pbuf !=NULL && size > 0)
{
for (i = 0; i < size; i++) {
printf("%02x ", *((unsigned char *)pbuf + i));
}
putchar('\n');
}
putchar('\n');
}
EC_KEY *genECDHpubkey(unsigned char *pubkey, size_t& lenn)
{
size_t len;
int ret;
//Generate Public
EC_KEY *ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); // NID_secp521r1
//或者
//EC_KEY *ecdh = EC_KEY_new();
//EC_GROUP *group_ = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1); // NID_secp256k1
//EC_KEY_set_group(ecdh, group_);
//
ret = EC_KEY_generate_key(ecdh);
//
const EC_POINT *point = EC_KEY_get0_public_key(ecdh);//傳輸給對方的公鑰
const EC_GROUP *group = EC_KEY_get0_group(ecdh);
//
BIGNUM *x = BN_new();
BIGNUM *y = BN_new();
if (EC_POINT_get_affine_coordinates_GFp(group, point, x, y, NULL))
{
BN_print_fp(stdout, x);
putc('\n', stdout);
BN_print_fp(stdout, y);
putc('\n', stdout);
}
BN_free(x);
BN_free(y);
//將公鑰由POINT格式轉成OCT字符串
if (0 == (len = EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED, pubkey, ECDH_SIZE, NULL)))
{
handleErrors();
}
printf("len=%d\n",len);
disp("pubkey", pubkey, len);
lenn = len;
return ecdh;
}
unsigned char *genECDHsharedsecret(EC_KEY *ecdh, unsigned char *peerkey, size_t secret_len)
{
int len, ret;
unsigned char *shared = (unsigned char *)malloc(ECDH_SIZE);
const EC_GROUP *group = EC_KEY_get0_group(ecdh);
//ComputeKey
EC_POINT *point_peer = EC_POINT_new(group);
if (0 == (ret = EC_POINT_oct2point(group, point_peer, peerkey, secret_len, NULL))) // ECDH_SIZE
{
handleErrors();
}
//
if (0 == (len = ECDH_compute_key(shared, ECDH_SIZE-1, point_peer, ecdh, NULL)))
{
handleErrors();
}
printf("len=%d\n",len);
disp("shared", shared, len);
return shared;
}
int testECDH()
{
unsigned char *keydata = (unsigned char *)malloc(ECDH_SIZE);
unsigned char *keydata2 = (unsigned char *)malloc(ECDH_SIZE);
size_t len1 = 0, len2 = 0;
EC_KEY *ecdh = genECDHpubkey(keydata, len1);
EC_KEY *ecdh2 = genECDHpubkey(keydata2, len2);
unsigned char *ECDH_keydata = genECDHsharedsecret(ecdh2, keydata, len1);//ECDH_SIZE-1
unsigned char *ECDH_keydata2 = genECDHsharedsecret(ecdh, keydata2, len2);//ECDH_SIZE-1
if (0== memcmp(ECDH_keydata, ECDH_keydata2, ECDH_SIZE - 1)) //算出來的共享密鑰必須相同
{
printf("------sharedsecret ok------\n");
}
printf("To the end\n");
free(keydata);
free(keydata2);
EC_KEY_free(ecdh);
EC_KEY_free(ecdh2);
free(ECDH_keydata);
free(ECDH_keydata2);
return 0;
}
int main8(int argc, char *argv[])
{
return testECDH();
}
運行結果:
shared密鑰就是我們後續採用AES等對稱算法的Key。
參考:
https://www.cnblogs.com/Kalafinaian/p/7392505.html
https://bbs.csdn.net/topics/360001596
https://www.freebuf.com/articles/database/155912.html
https://my.oschina.net/safedead/blog/515386
https://www.cnblogs.com/10zhang/p/9381897.html
https://blog.csdn.net/bravegogo/article/details/63684286