Trusted Design

OpenSSLでECDSA鍵生成

概要

OpenSSLが提供しているC言語のAPIを使って公開鍵暗号方式であるECDSAの鍵生成をします。楕円暗号アルゴリズムはRSAと比較して短い鍵長で同じ強度の暗号処理ができるため,利用されるようになってきました。

利用するAPI

ECDSA鍵生成を実行するためのAPI

  • EC_KEY_new()
    EC_KEYオブジェクトを生成します。
  • EC_GROUP_new_by_curve_name()
    楕円曲線名を指定してEC_GROUPオブジェクトを生成します。
  • EC_KEY_set_group()
    EC_KEYとEC_GROUPを関連付けます。
  • EC_KEY_generate_key()
    ECDSA鍵を生成します。
  • EC_GROUP_free()
    EC_GROUPオブジェクトを解放します。
  • EC_KEY_free()
    EC_KEYオブジェクトを解放します。
  • i2d_ECPrivateKey()
    ECDSA鍵を出力します。

サンプルプログラム

ECDSA鍵を生成する。

この例では192bitの鍵を生成します。OpenSSLはもっと鍵長が長い鍵もサポートしています。


#include "openssl/ec.h"
#include "openssl/ecdsa.h"
#include "openssl/err.h"
#include "openssl/obj_mac.h"

/*
 バイト列を出力する関数
*/
int PrintBytes(unsigned char* bytes, unsigned int bytesLen)
{
	for (int i = 1; i <= bytesLen; i++) {
		printf("%02x ", *bytes++);
		if (i % 16 == 0) printf("\n");
	}
	printf("\n");
	return 1;
}

int main()
{
    EC_KEY* ecKey = NULL;
    EC_GROUP* ecGroup = NULL;
    int nid = NID_secp192k1;        // 実際はもっと長い鍵長での利用を推奨

    unsigned char* buff;
    unsigned char* work;
    int bufLen = 0;
    /* EC_KEYオブジェクトを生成する */
    ecKey = EC_KEY_new();
    if (NULL == ecKey)
    {
        printf("Error: %s\n", ERR_reason_error_string(ERR_get_error()));
        return 0;
    }

    /* EC_GROUPオブジェクトを生成する */
    ecGroup = EC_GROUP_new_by_curve_name(nid);
    if (NULL == ecGroup)
    {
        printf("Error: %s\n", ERR_reason_error_string(ERR_get_error()));
        return 0;
    }

    /* EC_KEYをEC_GROUPと関連付ける */
    if (!EC_KEY_set_group(ecKey, ecGroup))
    {
        printf("Error: %s\n", ERR_reason_error_string(ERR_get_error()));
        return 0;
    }

    /* 鍵を生成する */
    if (!EC_KEY_generate_key(ecKey))
    {
        printf("Error: %s\n", ERR_reason_error_string(ERR_get_error()));
        return 0;
    }

    /* 鍵を出力する */
    bufLen = i2d_ECPrivateKey(ecKey, NULL);
    buff = work = (unsigned char*)malloc(bufLen);
    i2d_ECPrivateKey(ecKey, &work);
    PrintBytes(buff, bufLen);
    free(buff);

    /* 解放処理 */
    EC_GROUP_free(ecGroup);
    EC_KEY_free(ecKey);
    return 1;
}

実行結果

鍵のバイナリ列が出力されます。どのようなフォーマットで出力されているのか,よくわかってないです。ごめんなさい。


30 5c 02 01 01 04 18 31 7f f3 17 b8 52 ce a3 96
47 81 ac 5c 53 ee 47 45 47 74 c6 7b 21 ee fe a0
07 06 05 2b 81 04 00 1f a1 34 03 32 00 04 5d 01
f9 54 08 e4 d8 42 2c cd b4 e0 05 02 47 3f 09 8b
86 bd fb 8b 71 3e 5c 95 55 92 93 a5 8d d4 cd 34
c1 ca 4b 67 9b db 6d b5 9a d1 e2 eb 28 9f