openssl學習(二) 橢圓曲線

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很龐大,某一個功能,可使用多種方法來實現.學習頭文件,是一個比較不錯的辦法.數據結構

相關文章
相關標籤/搜索