openssl学习(二) 椭圆曲线
椭圆曲线(ECC)算法是一种公钥算法,功能同RSA同样,可是,相比与RSA,ECC处理速度更快,占用空间也小,毕竟它长度比RSA小得多.
openssl实现的ECC算法系列包括三部分,ECC 算法(crypto/ec)、椭圆曲线数字签名算法 ECDSA (crypto/ecdsa)以及椭圆曲线密钥交换算法 ECDH(crypto/dh)。
这里主要以签名为例.算法
#include <stdio.h> #include <string.h> #include <openssl/ec.h> #include <openssl/ecdsa.h> #include <openssl/objects.h> #include <openssl/err.h> #include <openssl/sha.h> int main(void) { int rc = 0; int nid = 0; EC_KEY *key = NULL; EC_GROUP *group = NULL; EC_builtin_curve *curves = NULL; int crv_len = 0; int key_size = 0; unsigned char hash_data[20] = {0}; unsigned char sign[256] = {0}; unsigned int sign_len = 0; unsigned char message[] = "abcdefghijklmnopqrstuvwxyz1234567890"; /* 构造EC_KEY数据结构 */ key = EC_KEY_new(); if (key == NULL) { printf("EC_KEY_new err.\n"); return 0; } /* 获取实现的椭圆曲线个数 */ crv_len = EC_get_builtin_curves(NULL, 0); curves = (EC_builtin_curve *)calloc(sizeof(EC_builtin_curve) * crv_len, 1); EC_get_builtin_curves(curves, crv_len); #if 0 for (int i = 0; i < crv_len; i++) { printf("***** %d *****\n", i); printf("nid = %d\n", curves[i].nid); printf("comment = %s\n", curves[i].comment); } #endif /* 选择一种椭圆曲线 */ nid = OBJ_sn2nid("SM2"); /* 根据选择的椭圆曲线生成密钥参数 group */ group = EC_GROUP_new_by_curve_name(nid); if (group == NULL) { printf("EC_GROUP_new_by_curve_name err!\n"); return -1; } /* 设置密钥参数 */ rc = EC_KEY_set_group(key, group); if (rc != 1) { printf("EC_KEY_set_group err.\n"); return -1; } /* 生成密钥 */ rc = EC_KEY_generate_key(key); if (rc != 1) { printf("EC_KEY_generate_key err.\n"); return 0; } /* 检查密钥 */ rc = EC_KEY_check_key(key); if (rc != 1) { printf("check key err.\n"); return 0; } key_size = ECDSA_size(key); printf("key_size = %d\n", key_size); SHA1(message, strlen((char *)message), hash_data); // sign. 第一个参数0,该参数忽略. rc = ECDSA_sign(0, hash_data, 20, sign, &sign_len, key); if (rc != 1) { printf("ECDSA_sign err.\n"); return 0; } printf("sign success.\n"); // verify, 第一个参数同sign rc = ECDSA_verify(0, hash_data, 20, sign, sign_len, key); if (rc != 1) { printf("ECDSA_verify err.\n"); return 0; } printf("verify success.\n"); EC_GROUP_free(group), group = NULL; EC_KEY_free(key), key = NULL; free(curves), curves = NULL; return 0; }
这个代码例子主要是用最基础的一些结构体,在实际使用过程当中,会涉及到密钥的转换,密钥结构体构建等,将在后续的EVP以及编解码等学习中慢慢练习.
openssl很庞大,某一个功能,可使用多种方法来实现.学习头文件,是一个比较不错的办法.数据结构