記事の概要
mbet TLSを用いてRSAを利用します。
今回はRSAの公開鍵と秘密鍵の作成を行います。
サンプルプログラムは以下に置いてあります。
https://github.com/matsuikosuke/mbedTLSTest
サンプルコード
static int entropy_dummy_source( void *data, unsigned char *output,
size_t len, size_t *olen )
{
((void) data);
memset( output, 0x2a, len );
*olen = len;
return( 0 );
}
int mbedtls_rsa_key_generation_test(void)
{
int ret = 1;
size_t olen = msg_len;
mbedtls_pk_context p_pk;
mbedtls_rsa_context *p_rsa;
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
const char* pers = "rsa_genkey";
mbedtls_entropy_init(&entropy);
mbedtls_ctr_drbg_init(&ctr_drbg);
mbedtls_entropy_add_source( &entropy, entropy_dummy_source, NULL,
32, MBEDTLS_ENTROPY_SOURCE_STRONG );
ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,
(const unsigned char*)pers,
strlen(pers));
if (ret != 0)
return ret;
mbedtls_rsa_init( p_rsa, MBEDTLS_RSA_PKCS_V15, 0 );
mbedtls_pk_init(&p_pk);
ret = mbedtls_pk_setup( &p_pk, mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) );
if (ret != 0)
return ret;
p_rsa = mbedtls_pk_rsa( p_pk );
ret = mbedtls_rsa_gen_key(p_rsa, mbedtls_ctr_drbg_random, &ctr_drbg, 2048, 0x010001);
if (ret != 0)
return ret;
uint8_t private_key_pem[8000];
uint8_t publick_key_pem[8000];
ret = mbedtls_pk_write_key_pem(&p_pk, private_key_pem, sizeof(private_key_pem));
if (ret != 0)
return ret;
ret = mbedtls_pk_write_pubkey_pem(&p_pk, publick_key_pem, sizeof(publick_key_pem));
if (ret != 0)
return ret;
return ret;
}
乱数の作成
乱数を作成します。
mbedtls_entropy_init(&entropy);
mbedtls_ctr_drbg_init(&ctr_drbg);
mbedtls_entropy_add_source( &entropy, entropy_dummy_source, NULL,
32, MBEDTLS_ENTROPY_SOURCE_STRONG );
ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,
(const unsigned char*)pers,
strlen(pers));
if (ret != 0)
return ret;
公開鍵と秘密鍵の作成
mbedtls_rsa_init( p_rsa, MBEDTLS_RSA_PKCS_V15, 0 );
mbedtls_pk_init(&p_pk);
ret = mbedtls_pk_setup( &p_pk, mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) );
if (ret != 0)
return ret;
p_rsa = mbedtls_pk_rsa( p_pk );
ret = mbedtls_rsa_gen_key(p_rsa, mbedtls_ctr_drbg_random, &ctr_drbg, 2048, 0x010001);
if (ret != 0)
return ret;
mbedtls_rsa_gen_key()
の第4引数で生成するbit数を指定します。2048bit(256byte)の場合、かなり長い時間を要します。
第5引数は公開指数です。
PEM形式への変換
作成した公開鍵と秘密鍵は、そのままでは外部に渡せるデータ形式になっていないので、PEM形式に変換します。
uint8_t private_key_pem[8000];
uint8_t publick_key_pem[8000];
ret = mbedtls_pk_write_key_pem(&p_pk, private_key_pem, sizeof(private_key_pem));
if (ret != 0)
return ret;
ret = mbedtls_pk_write_pubkey_pem(&p_pk, publick_key_pem, sizeof(publick_key_pem));
if (ret != 0)
return ret;
DER形式に変換する関数もあります。
詳細は以下をご参照ください
https://tls.mbed.org/api/pk_8h.html#af5b7c3953ad6fe8be09d35508ee569f6
暗号化と復号
余談ですが、サンプルコードで作成したcontextp_rsa
を暗号化と復号の関数に代入すれば、暗号化と復号を実行できます
ret = mbedtls_rsa_rsaes_pkcs1_v15_encrypt(p_rsa,
mbedtls_ctr_drbg_random, &ctr_drbg,
MBEDTLS_RSA_PUBLIC,
32, &g_plaintext[0], &rsa_encrypted_buf[0]);
if (ret != 0)
return ret;
ret = mbedtls_rsa_rsaes_pkcs1_v15_decrypt(p_rsa,
mbedtls_ctr_drbg_random, &ctr_drbg,
MBEDTLS_RSA_PRIVATE,
&olen, rsa_encrypted_buf, rsa_decrypted_buf, 32);
if (ret != 0)
return ret;
参照
mbed TLSでAES-GCMを利用する
mbed TLSでRSAを利用する「RSA-OAEPの暗号化と復号」
mbed TLSでRSAを利用する「RSAの公開鍵と秘密鍵の作成」
mbed TLSおよびOberonでECDHを利用する
mbed TLSでHKDFを利用する
mbed TLSでJWTを利用する