openssl开源程序dh算法解析之dh_key.c
来源:互联网 发布:易燃易爆炸 知乎 编辑:程序博客网 时间:2024/05/17 04:07
/*实现openssl 提供的默认的DH_METHOD,实现了根据密钥参数生成DH公私钥,以及根据DH 公钥(一方)以及DH 私钥(另一方)来生成一个共享密钥,用于密钥交换*/#include <stdio.h>#include "cryptlib.h"#include <openssl/bn.h>#include <openssl/rand.h> //实现了伪随机数生成,支持用户自定义随机数生成#include <openssl/dh.h>static int generate_key(DH *dh);static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh);static int dh_bn_mod_exp(const DH *dh, BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); //r=a^p % mstatic int dh_init(DH *dh);static int dh_finish(DH *dh);int DH_generate_key(DH *dh) //生成公私钥{#ifdef OPENSSL_FIPS if (FIPS_mode() && !(dh->meth->flags & DH_FLAG_FIPS_METHOD) && !(dh->flags & DH_FLAG_NON_FIPS_ALLOW)) { DHerr(DH_F_DH_GENERATE_KEY, DH_R_NON_FIPS_METHOD); return 0; }#endif return dh->meth->generate_key(dh); //生成公私钥,存放于dh结构体的公私钥属性中}//根据对方公钥和己方DH 密钥来生成共享密钥的函数int DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh){#ifdef OPENSSL_FIPS if (FIPS_mode() && !(dh->meth->flags & DH_FLAG_FIPS_METHOD) && !(dh->flags & DH_FLAG_NON_FIPS_ALLOW)) { DHerr(DH_F_DH_COMPUTE_KEY, DH_R_NON_FIPS_METHOD); return 0; }#endif return dh->meth->compute_key(key, pub_key, dh); //结果保存在key中}int DH_compute_key_padded(unsigned char *key, const BIGNUM *pub_key, DH *dh){ int rv, pad; rv = dh->meth->compute_key(key, pub_key, dh); if (rv <= 0) return rv; pad = BN_num_bytes(dh->p) - rv; //返回dh->p的字节数 if (pad > 0) { memmove(key + pad, key, rv); memset(key, 0, pad); } return rv + pad;}static DH_METHOD dh_ossl = { "OpenSSL DH Method", generate_key, compute_key, dh_bn_mod_exp, dh_init, dh_finish, 0, NULL, NULL};const DH_METHOD *DH_OpenSSL(void){ return &dh_ossl;}static int generate_key(DH *dh) //被DH_generate_key调用,这里具体实现{ int ok = 0; int generate_new_key = 0; unsigned l; BN_CTX *ctx; //新建上下文结构 BN_MONT_CTX *mont = NULL; BIGNUM *pub_key = NULL, *priv_key = NULL; ctx = BN_CTX_new(); if (ctx == NULL) goto err; if (dh->priv_key == NULL) { priv_key = BN_new(); //获取私钥 if (priv_key == NULL) goto err; generate_new_key = 1; } else priv_key = dh->priv_key; if (dh->pub_key == NULL) { pub_key = BN_new(); //获取公钥,暂时的 if (pub_key == NULL) goto err; } else pub_key = dh->pub_key; if (dh->flags & DH_FLAG_CACHE_MONT_P) { mont = BN_MONT_CTX_set_locked(&dh->method_mont_p, CRYPTO_LOCK_DH, dh->p, ctx); if (!mont) goto err; } if (generate_new_key) { if (dh->q) { do { if (!BN_rand_range(priv_key, dh->q))//确保priv_key<dh->q goto err; } while (BN_is_zero(priv_key) || BN_is_one(priv_key)); } else { /* secret exponent length */ l = dh->length ? dh->length : BN_num_bits(dh->p) - 1; if (!BN_rand(priv_key, l, 0, 0)) goto err; } } { BIGNUM local_prk; BIGNUM *prk; if ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) == 0) { BN_init(&local_prk); prk = &local_prk; BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME); } else prk = priv_key; //真正产生公钥 if (!dh->meth->bn_mod_exp(dh, pub_key, dh->g, prk, dh->p, ctx, mont)) goto err; } dh->pub_key = pub_key; //将公私钥赋值到dh结构 dh->priv_key = priv_key; ok = 1; err: if (ok != 1) DHerr(DH_F_GENERATE_KEY, ERR_R_BN_LIB); if ((pub_key != NULL) && (dh->pub_key == NULL)) BN_free(pub_key); if ((priv_key != NULL) && (dh->priv_key == NULL)) BN_free(priv_key); BN_CTX_free(ctx); return (ok);}//被DH_compute_key调用,这里具体实现static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) { BN_CTX *ctx = NULL; BN_MONT_CTX *mont = NULL; BIGNUM *tmp; int ret = -1; int check_result; if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) { DHerr(DH_F_COMPUTE_KEY, DH_R_MODULUS_TOO_LARGE); goto err; } ctx = BN_CTX_new(); //新建上下文结构 if (ctx == NULL) goto err; BN_CTX_start(ctx); tmp = BN_CTX_get(ctx); if (dh->priv_key == NULL) { DHerr(DH_F_COMPUTE_KEY, DH_R_NO_PRIVATE_VALUE); goto err; } if (dh->flags & DH_FLAG_CACHE_MONT_P) { mont = BN_MONT_CTX_set_locked(&dh->method_mont_p, CRYPTO_LOCK_DH, dh->p, ctx); if ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) == 0) { /* XXX */ BN_set_flags(dh->priv_key, BN_FLG_CONSTTIME); } if (!mont) goto err; } if (!DH_check_pub_key(dh, pub_key, &check_result) || check_result) {//检查公钥合理性 DHerr(DH_F_COMPUTE_KEY, DH_R_INVALID_PUBKEY); goto err; } if (!dh-> //tep=pub_key ^ dh->priv_key % dh->p,tmp就是key meth->bn_mod_exp(dh, tmp, pub_key, dh->priv_key, dh->p, ctx, mont)) { DHerr(DH_F_COMPUTE_KEY, ERR_R_BN_LIB); goto err; } ret = BN_bn2bin(tmp, key); //转换为字节存储方式:大端法,存入key中 err: if (ctx != NULL) { BN_CTX_end(ctx); BN_CTX_free(ctx); } return (ret);}static int dh_bn_mod_exp(const DH *dh, BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx){ /* * If a is only one word long and constant time is false, use the faster * exponenentiation function. */ if (a->top == 1 && ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) != 0)) { BN_ULONG A = a->d[0]; return BN_mod_exp_mont_word(r, A, p, m, ctx, m_ctx); } else return BN_mod_exp_mont(r, a, p, m, ctx, m_ctx);}static int dh_init(DH *dh) //初始化函数{ dh->flags |= DH_FLAG_CACHE_MONT_P; return (1);}static int dh_finish(DH *dh) //结束函数{ if (dh->method_mont_p) BN_MONT_CTX_free(dh->method_mont_p); return (1);}
0 0
- openssl开源程序dh算法解析之dh_key.c
- openssl开源程序dh算法解析之dh_ameth.c
- openssl开源程序dh算法解析之dh_check.c
- openssl开源程序dh算法解析之dh_gen.c
- openssl开源程序dh算法解析之p1024.c
- 《openssl 编程》之 DH
- openssl中dh算法实现
- openssl中dh算法Demo
- openssl中dh算法Demo
- OpenCSP开源程序解析之OPENCSP_Alg.cpp
- OpenCSP开源程序解析之OPENCSP_AuthUI.cpp
- OpenCSP开源程序解析之OPENCSP_Hash.cpp
- OpenCSP开源程序解析之OPENCSP_Key.cpp
- OpenCSP开源程序解析之OPENCSP_Keyset.cpp
- OpenCSP开源程序解析之OPENCSP_Main.cpp
- OpenCSP开源程序解析之OPENCSP_Mutex.cpp
- openssl DH密钥协商
- DH算法
- java反射机制详解 及 Method.invoke解释
- Android 清理应用缓存
- 阿猿,你的工作在混日子吗?
- C++基础学习(04PM)
- 采集和输出 DeckLink Studio 4K
- openssl开源程序dh算法解析之dh_key.c
- 狂刷Android范例之2:剪贴板范例
- make_heap topk 问题
- AcousticModel API 声学模型
- C++二叉查找树实现过程详解
- 第一题
- 分页例子
- 初学Spark
- JSP3大标签