GB35114---基于openssl加密库进行开发(二)
生活随笔
收集整理的這篇文章主要介紹了
GB35114---基于openssl加密库进行开发(二)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
接上篇GB35114---基于openssl加密庫進行開發(一)
-----------------------------------------------------------------------------------------------------------------------------
openssl的兩個.so動態庫libcrypto.so.1.1 and?libssl.so.1.1不能直接調用sm2簽名及加密函數。
但是它里面集成了sm2的橢圓曲線,那我們就根據sm2曲線算法直接寫個簽名函數。
其實在openssl的sm2_sign.c內已經有相關算法,那我們就伸手了。
BIGNUM *sm2_compute_msg_hash(const EVP_MD *digest,const EC_KEY *key,const uint8_t *id,const int id_len,const uint8_t *msg, int msg_len) {EVP_MD_CTX *hash = EVP_MD_CTX_new();const int md_size = EVP_MD_size(digest);uint8_t *z = NULL;BIGNUM *e = NULL;if (md_size < 0) {goto done;}z = OPENSSL_zalloc(md_size);if (hash == NULL || z == NULL) {goto done;}if (!sm2_compute_z_digest(z, digest, id, id_len, key)) {/* SM2err already called */goto done;}if (!EVP_DigestInit(hash, digest)|| !EVP_DigestUpdate(hash, z, md_size)|| !EVP_DigestUpdate(hash, msg, msg_len)/* reuse z buffer to hold H(Z || M) */|| !EVP_DigestFinal(hash, z, NULL)) {goto done;}e = BN_bin2bn(z, md_size, NULL);if (e == NULL)done:OPENSSL_free(z);EVP_MD_CTX_free(hash);return e; }static ECDSA_SIG *sm2_sig_gen(const EC_KEY *key, const BIGNUM *e) {const BIGNUM *dA = EC_KEY_get0_private_key(key);const EC_GROUP *group = EC_KEY_get0_group(key);const BIGNUM *order = EC_GROUP_get0_order(group);ECDSA_SIG *sig = NULL;EC_POINT *kG = NULL;BN_CTX *ctx = NULL;BIGNUM *k = NULL;BIGNUM *rk = NULL;BIGNUM *r = NULL;BIGNUM *s = NULL;BIGNUM *x1 = NULL;BIGNUM *tmp = NULL;kG = EC_POINT_new(group);ctx = BN_CTX_new();if (kG == NULL || ctx == NULL) {goto done;}BN_CTX_start(ctx);k = BN_CTX_get(ctx);rk = BN_CTX_get(ctx);x1 = BN_CTX_get(ctx);tmp = BN_CTX_get(ctx);if (tmp == NULL) {goto done;}/** These values are returned and so should not be allocated out of the* context*/r = BN_new();s = BN_new();if (r == NULL || s == NULL) {goto done;}for (;;) {if (!BN_priv_rand_range(k, order)) {goto done;}if (!EC_POINT_mul(group, kG, k, NULL, NULL, ctx)|| !EC_POINT_get_affine_coordinates(group, kG, x1, NULL,ctx)|| !BN_mod_add(r, e, x1, order, ctx)) {goto done;}/* try again if r == 0 or r+k == n */if (BN_is_zero(r))continue;if (!BN_add(rk, r, k)) {goto done;}if (BN_cmp(rk, order) == 0)continue;if (!BN_add(s, dA, BN_value_one())|| !ec_group_do_inverse_ord(group, s, s, ctx)|| !BN_mod_mul(tmp, dA, r, order, ctx)|| !BN_sub(tmp, k, tmp)|| !BN_mod_mul(s, s, tmp, order, ctx)) {goto done;}sig = ECDSA_SIG_new();if (sig == NULL) {goto done;}/* takes ownership of r and s */ECDSA_SIG_set0(sig, r, s);break;}done:if (sig == NULL) {BN_free(r);BN_free(s);}BN_CTX_free(ctx);EC_POINT_free(kG);return sig; }ECDSA_SIG *sm2_do_sign(const EC_KEY *key,const EVP_MD *digest,const uint8_t *id,const int id_len,const uint8_t *msg, int msg_len) {BIGNUM *e = NULL;ECDSA_SIG *sig = NULL;e = sm2_compute_msg_hash(digest, key, id, id_len, msg, msg_len);if (e == NULL) {/* SM2err already called */goto done;}sig = sm2_sig_gen(key, e);done:BN_free(e);return sig; }其中
sm2_compute_msg_hash? ?函數是對簽名數據進行hash散列;
sm2_sig_gen? ?函數是SM2簽名算法,注:該函數最后調用ECDSA_SIG_set0(sig, r, s)對SM2真正的簽名的r跟s進行了轉化,返回ECDSA_SIG結構的簽名數據。
至此SM2-SM3的簽名函數就搞定了,我們依葫蘆畫瓢完成驗簽、加解密等函數。
最后附上可用的代碼,也是我過gb35114的加密代碼。
SM2-SM3示例代碼
?
有錯誤請留言,謝謝
下篇
GB35114---聊聊SM2簽名格式
---bob? 2020/3/17 10.44
總結
以上是生活随笔為你收集整理的GB35114---基于openssl加密库进行开发(二)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用Python批量转换图片格式
- 下一篇: 一款软件测试脚本生成工具