.h文件
#ifndef __ECDH_H_
#define __ECDH_H_
#include <string>
namespace qq{
typedef void EC_KEY;
typedef void EC_GROUP;
typedef void EC_POINT;
typedef void BN_CTX;
typedef enum {
/** the point is encoded as z||x, where the octet z specifies
* which solution of the quadratic equation y is */
POINT_CONVERSION_COMPRESSED = 2,
/** the point is encoded as z||x||y, where z is the octet 0x04 */
POINT_CONVERSION_UNCOMPRESSED = 4,
/** the point is encoded as z||x||y, where the octet z specifies
* which solution of the quadratic equation y is */
POINT_CONVERSION_HYBRID = 6
} point_conversion_form_t;
typedef EC_KEY* (__cdecl *PFN_EC_KEY_new_by_curve_name)(int nid);
typedef EC_GROUP* (__cdecl *PFN_EC_KEY_get0_group)(EC_KEY* ecKey);
typedef EC_POINT* (__cdecl *PFN_EC_POINT_new)(const EC_GROUP *group);
typedef int(__cdecl *PFN_EC_KEY_generate_key)(EC_KEY* ecKey);
typedef int(__cdecl *PFN_EC_POINT_point2oct)(const EC_GROUP *group, const EC_POINT *p, point_conversion_form_t form, unsigned char *buf, size_t len, BN_CTX *ctx);
typedef const EC_POINT* (__cdecl *PFN_EC_KEY_get0_public_key)(const EC_KEY *key);
typedef int(__cdecl *PFN_EC_POINT_oct2point)(const EC_GROUP *group, EC_POINT *p, const unsigned char *buf, size_t len, BN_CTX *ctx);
typedef int(__cdecl *PFN_ECDH_compute_key)(void *out, size_t outlen, const EC_POINT *pub_key, const EC_KEY *ecdh, void *(*KDF) (const void *in, size_t inlen, void *out, size_t *outlen));
#define NID_secp192k1 711
class ECDH{
public:
ECDH();
~ECDH();
private:
void* m_pEC_Key;
void* m_pEC_Group;
void* m_pEC_Point;
PFN_EC_KEY_new_by_curve_name EC_KEY_new_by_curve_name;
PFN_EC_KEY_get0_group EC_KEY_get0_group;
PFN_EC_POINT_new EC_POINT_new;
PFN_EC_KEY_generate_key EC_KEY_generate_key;
PFN_EC_POINT_point2oct EC_POINT_point2oct;
PFN_EC_KEY_get0_public_key EC_KEY_get0_public_key;
PFN_EC_POINT_oct2point EC_POINT_oct2point;
PFN_ECDH_compute_key ECDH_compute_key;
public:
bool First(std::string& strPublic, std::string& strShare);
std::string Twice(unsigned char* tk);
};
}
#endif
.cpp文件
#include "StdAfx.h"
#include "ECDH.h"
#include "../Util/string_ext.h"
namespace qq {
ECDH::ECDH() :
m_pEC_Key(NULL),
m_pEC_Group(NULL),
m_pEC_Point(NULL)
{
HMODULE hModule = ::LoadLibrary("libeay32.dll");
if (hModule == NULL)
{
MessageBox(0, "请检查目录下是否存在libeay32.dll!", "错误", MB_ICONERROR|MB_OK);
exit(0);
}
EC_KEY_new_by_curve_name = (PFN_EC_KEY_new_by_curve_name)::GetProcAddress(hModule, "EC_KEY_new_by_curve_name");
EC_KEY_get0_group = (PFN_EC_KEY_get0_group)::GetProcAddress(hModule, "EC_KEY_get0_group");
EC_POINT_new = (PFN_EC_POINT_new)::GetProcAddress(hModule, "EC_POINT_new");
EC_KEY_generate_key = (PFN_EC_KEY_generate_key)::GetProcAddress(hModule, "EC_KEY_generate_key");
EC_POINT_point2oct = (PFN_EC_POINT_point2oct)::GetProcAddress(hModule, "EC_POINT_point2oct");
EC_KEY_get0_public_key = (PFN_EC_KEY_get0_public_key)::GetProcAddress(hModule, "EC_KEY_get0_public_key");
EC_POINT_oct2point = (PFN_EC_POINT_oct2point)::GetProcAddress(hModule, "EC_POINT_oct2point");
ECDH_compute_key = (PFN_ECDH_compute_key)::GetProcAddress(hModule, "ECDH_compute_key");
}
ECDH::~ECDH()
{
}
bool ECDH::First(std::string& strPublic, std::string& strShare)
{
strPublic = _T("");
strShare = _T("");
//QQ的tk,不同版本可能会变,这里是8.9的
unsigned char tk[49] = { 0x04, 0xBF, 0x47, 0xA1, 0xCF, 0x78, 0xA6, 0x29, 0x66, 0x8B,
0x0B, 0xC3, 0x9F, 0x8E, 0x54, 0xC9, 0xCC, 0xF3, 0xB6, 0x38,
0x4B, 0x08, 0xB8, 0xAE, 0xEC, 0x87, 0xDA, 0x9F, 0x30, 0x48,
0x5E, 0xDF, 0xE7, 0x67, 0x96, 0x9D, 0xC1, 0xA3, 0xAF, 0x11,
0x15, 0xFE, 0x0D, 0xCC, 0x8E, 0x0B, 0x17, 0xCA, 0xCF
};
unsigned char ucPublic[25] = {0};
unsigned char ucShare[16] = {0};
m_pEC_Key = EC_KEY_new_by_curve_name(NID_secp192k1);
m_pEC_Group = EC_KEY_get0_group(m_pEC_Key);
m_pEC_Point = EC_POINT_new(m_pEC_Group);
if (EC_KEY_generate_key(m_pEC_Key) == 1){
EC_POINT_point2oct(m_pEC_Group, EC_KEY_get0_public_key(m_pEC_Key), POINT_CONVERSION_COMPRESSED, ucPublic, 25, 0);
if (EC_POINT_oct2point(m_pEC_Group, m_pEC_Point, tk, 49, 0) == 1){
ECDH_compute_key(ucShare, 16, m_pEC_Point, m_pEC_Key, 0);
}
}
strPublic = byte_to_hexstr(ucPublic, 25);
strShare = byte_to_hexstr(ucShare, 16);
return true;
}
std::string ECDH::Twice(unsigned char* tk)
{
unsigned char ucShare[16] = { 0 };
if (EC_POINT_oct2point(m_pEC_Group, m_pEC_Point, tk, 49, 0) == 1)
ECDH_compute_key(ucShare, 16, m_pEC_Point, m_pEC_Key, 0);
return byte_to_hexstr(ucShare, 16);
}
}