当前位置: 首页 > news >正文

用服务器ip做网站域名/百度问答平台

用服务器ip做网站域名,百度问答平台,网站建设图片排版,网站设计方案大全由于项目需要,使用openssl编写一段ECDH代码实现网络两端实体的密钥交换。虽然对openssl不熟悉,但也开始做。最先参照的是openssl官方wiki上的Elliptic Curve Diffie Hellman:http://wiki.openssl.org/index.php/Elliptic_Curve_Diffie_Hellma…

由于项目需要,使用openssl编写一段ECDH代码实现网络两端实体的密钥交换。

虽然对openssl不熟悉,但也开始做。

最先参照的是openssl官方wiki上的Elliptic Curve Diffie Hellman:http://wiki.openssl.org/index.php/Elliptic_Curve_Diffie_Hellman

直接使用文中的代码。不过其中有段代码需要替换:

/* Get the peer's public key, and provide the peer with our public key -

* how this is done will be specific to your circumstances */

peerkey = get_peerkey(pkey);

我以为只要将这pkey和peerkey指向的密钥块通过网络交换一下就行了。

先不经过网络交换这两个密钥数据,在本地测试,完全通过。但是,一涉及网络交换,程序就崩溃,并爆出内存错误。

总以为是外围程序的问题,调试了好久好久……

直到后来,最后打印出pkey和peerkey指向的类型为EVP_PKEY的数据来看,才发现EVP_PKEY占存储量很小(32字节),这才发现奇怪。因为密钥块一般挺大的。

在openssl库安装路径include目录中找到evp.h,打开查看,发现:

struct evp_pkey_st

{

int type;

int save_type;

int references;

const EVP_PKEY_ASN1_METHOD *ameth;

ENGINE *engine;

union{

char *ptr;

#ifndef OPENSSL_NO_RSA

struct rsa_st *rsa;/* RSA */

#endif

#ifndef OPENSSL_NO_DSA

struct dsa_st *dsa;/* DSA */

#endif

#ifndef OPENSSL_NO_DH

struct dh_st *dh;/* DH */

#endif

#ifndef OPENSSL_NO_EC

struct ec_key_st *ec;/* ECC */

#endif

} pkey;

int save_parameters;

STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */

} /* EVP_PKEY */;

这下明白了,原来在网络上传输的我以为的“密钥块”原来是一堆指针!(而且是公私密钥对的指针。。。。)

于是得想办法解决。找到这个帖子:

How does one access the raw ECDH public key, private key and params inside OpenSSL's EVP_PKEY structure?

http://stackoverflow.com/questions/18155559/how-does-one-access-the-raw-ecdh-public-key-private-key-and-params-inside-opens

文中指出要进行公钥的序列化。

然后挨个搜索API的说明,花了不少时间。又是一阵子调试……

最后还是卡在反序列化过程中EC_KEY_set_public_key() to get an EC_KEY和EC_KEY to EVP_PKEY_set1_EC_KEY上了。

心想只好换一种方法了。调试途中在google搜索EC_POINT_point2oct关键字时发现了一个页面:

OpenSSL - User - ECDH http://openssl.6102.n7.nabble.com/ECDH-td22150.html

3楼Rick的回复给的代码比较好。采用并改进,调试之。

最终得到完整的ECDH代码:

#include

#define ECDH_SIZE 33

void handleErrors()

{

printf("Error occurred.\n");

}

static 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

printf("%02x ", *((unsigned char *)pbuf+i));

putchar('\n');

}

putchar('\n');

}

int main() {

/* alice */

EC_KEY *ecdh = EC_KEY_new();

EC_POINT *point = NULL;

EC_POINT *point2c;

EC_GROUP *group;

unsigned char pubkey[ECDH_SIZE];

unsigned char shared[ECDH_SIZE];

int len;

//Generate Public

ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);//NID_secp521r1

EC_KEY_generate_key(ecdh);

point = EC_KEY_get0_public_key(ecdh);

group = EC_KEY_get0_group(ecdh);

if(0 == (len = EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED, pubkey, ECDH_SIZE, NULL))) handleErrors();

printf("len=%d\n",len);

/* bob */

EC_KEY *ecdh2 = EC_KEY_new();

EC_POINT *point2 = NULL;

EC_POINT *pointc;

EC_GROUP *group2;

unsigned char pubkey2[ECDH_SIZE];

unsigned char shared2[ECDH_SIZE];

int len2;

//Generate Public

ecdh2 = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);//NID_secp521r1

EC_KEY_generate_key(ecdh2);

point2 = EC_KEY_get0_public_key(ecdh2);

group2 = EC_KEY_get0_group(ecdh2);

if(0 == (len2 = EC_POINT_point2oct(group2, point2, POINT_CONVERSION_COMPRESSED, pubkey2, ECDH_SIZE, NULL))) handleErrors();

printf("len2=%d\n",len);

/* alice */

//ComputeKey

point2c = EC_POINT_new(group);

EC_POINT_oct2point(group, point2c, pubkey2, ECDH_SIZE, NULL);

if (0 != EC_POINT_cmp(group, point2, point2c, NULL)) handleErrors();

if(0 == (len = ECDH_compute_key(shared, ECDH_SIZE, point2c, ecdh, NULL))) handleErrors();

printf("len=%d\n",len);

disp("shared", shared, len);

/* bob */

//ComputeKey

pointc = EC_POINT_new(group2);

EC_POINT_oct2point(group2, pointc, pubkey, ECDH_SIZE, NULL);

if (0 != EC_POINT_cmp(group2, point, pointc, NULL)) handleErrors();

if(0 == (len2 = ECDH_compute_key(shared2, ECDH_SIZE, pointc, ecdh2, NULL))) handleErrors();

printf("len2=%d\n",len2);

disp("shared2", shared2, len2);

/* alice */

EC_POINT_free(pointc);

EC_KEY_free(ecdh);

/* bob */

EC_POINT_free(point2c);

EC_KEY_free(ecdh2);

printf("To the end\n");

return 0;

}

之后抽象、整理封装后的ECDH代码:

#include

#define ECDH_SIZE 33

void handleErrors()

{

printf("Error occurred.\n");

}

static 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

printf("%02x ", *((unsigned char *)pbuf+i));

putchar('\n');

}

putchar('\n');

}

static EC_KEY *genECDHtemppubkey(unsigned char *pubkey)

{

int len;

EC_KEY *ecdh = EC_KEY_new();

//Generate Public

ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);//NID_secp521r1

EC_KEY_generate_key(ecdh);

const EC_POINT *point = EC_KEY_get0_public_key(ecdh);

const EC_GROUP *group = EC_KEY_get0_group(ecdh);

//unsigned char *pubkey = malloc(ECDH_SIZE);

if(0 == (len = EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED, pubkey, ECDH_SIZE, NULL))) handleErrors();

printf("len=%d\n",len);

//return pubkey;

return ecdh;

}

static unsigned char *genECDHsharedsecret(EC_KEY *ecdh, unsigned char *peerkey, size_t secret_len)

{

int len;

unsigned char *shared = malloc(ECDH_SIZE);

const EC_GROUP *group = EC_KEY_get0_group(ecdh);

//ComputeKey

EC_POINT *point_peer = EC_POINT_new(group);

EC_POINT_oct2point(group, point_peer, peerkey, ECDH_SIZE, NULL);

//if (0 != EC_POINT_cmp(group, point2, point2c, NULL)) handleErrors();

if(0 == (len = ECDH_compute_key(shared, secret_len, point_peer, ecdh, NULL))) handleErrors();

printf("len=%d\n",len);

disp("shared", shared, secret_len);

return shared;

}

int main() {

unsigned char *keydata = malloc(ECDH_SIZE);

unsigned char *keydata2 = malloc(ECDH_SIZE);

EC_KEY *ecdh = genECDHtemppubkey(keydata);

EC_KEY *ecdh2 = genECDHtemppubkey(keydata2);

unsigned char *ECDH_keydata = genECDHsharedsecret(ecdh2, keydata, ECDH_SIZE-1);

unsigned char *ECDH_keydata2 = genECDHsharedsecret(ecdh, keydata2, ECDH_SIZE-1);

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;

}

调试时在“ECDH_SIZE-1”的问题上纠结了好一阵子,不小心把EC_POINT_oct2point中参数ECDH_SIZE换成值为ECDH_SIZE-1的secret_len了;导致ECDH_compute_key一直返回-1,怎么搜索都得不到解决。

最后还是耐心的一步步调试、对比前面参考的源码、调整变量数值,终于解决。编译通过,执行的非常好。

耐心真的是非常重要,失之毫厘差之千里。

参考资料:

ECC加密算法原理入门介绍

http://blog.csdn.net/sahusoft/article/details/6868016

http://www.jmfq.cn/news/5092705.html

相关文章:

  • 政务咨询投诉举报网站建设/广州网络seo优化
  • wordpress电商网站/百度浏览器在线打开
  • 网站建设方案书制作流程/引流推广平台
  • 动态网站开发的集成软件有哪些/如何开网店
  • 深圳网站建设php/线下推广方式
  • 优秀的定制网站建设公司/网站优化技术
  • 我需要一个网站/网站建设策划方案
  • 北京给网站做系统的公司/下载百度卫星导航
  • 企业展厅设计内容/优化大师windows
  • 伍壹捌网站建设/制作网页
  • wordpress 内嵌网页/百度怎么优化网站排名
  • 专门做正品的网站手机版/网站快速被百度收录
  • 网站建设方案的企业/惠州seo网站推广
  • 网站建设包括网页设计/杭州seo论坛
  • 做电子网站/成都专门做网络推广的公司
  • 酒店网站开发协议/电商网站设计模板
  • 兰州网站建设公/福州seo排名优化公司
  • 东莞个人免费建网站/舆情分析系统
  • 融水做的比较好的网站有哪些/外链交易平台
  • 网站设计策划书 模板/网店推广方案范文
  • dz 一步一步教你做网站/免费网站代理访问
  • 网站建设自/企业网站推广方案
  • 网站建设及网站推广/百度联盟个人怎么接广告
  • 网站后台做图片尺寸是多大/网上推广赚钱项目
  • 网站怎么做301跳转/免费网站推广网站不用下载
  • 北京网站建设哪家好/百度指数pc版
  • 手工活接单在家做有正规网站吗/seo是谁
  • 如何用ps做网站/广告视频
  • wordpress 做公司网站/关键词搜索站长工具
  • 关于网站开发的开题报告/有哪些推广平台和渠道