解析 ECC 私钥缓冲区
Parse a ECC private key buffer
我正在使用 OPTEE-OS 和 mbedTLS 并想创建一个 CSR。我正在使用全球平台创建我的 EC 密钥 API:
res = TEE_AllocateTransientObject(
TEE_TYPE_ECDSA_KEYPAIR,
DSEC_ECDSA_SHA256_KEY_BITS,
&key_pair);
if (res != TEE_SUCCESS) {
return res;
}
然后提取私钥:
res = TEE_GetObjectBufferAttribute(
key_pair,
TEE_ATTR_ECC_PRIVATE_VALUE,
buffer,
&bufferlen);
if (res != TEE_SUCCESS) {
return res;
}
然后使用mbedTLS解析这个值并创建一个创建CSR:
mbedtls_pk_context priv_key;
mbedtls_pk_init(&priv_key);
ret = mbedtls_pk_parse_key(
&priv_key,
key,
size,
NULL ,
0
);
但是,从 TEE_GetObjectBufferAttribute 中提取的值没有页眉和页脚:
"-----BEGIN EC PRIVATE KEY-----"
"-----END EC PRIVATE KEY-----"
and 只是一个二进制数组(不是字符串)。我目前收到以下错误代码:"-15616: PK - Invalid key tag or value".
有什么方法可以只用我的私钥的二进制值创建 mbedtls_pk_context
吗?
Mbed TLS pk.h
中的解析函数需要 DER 或 PEM 输入。如果您可以找到现成的代码以从 OPTEE 中将密钥导出为 DER(或 PEM),那会更容易(但效率可能略低)。另一方面,手动导入比编写 DER 导出函数更容易。
您需要调用mbedtls_pk_setup()
声明上下文将包含ECC密钥,然后直接使用ecp.h
中的接口构建ECC密钥。将曲线名称从 TEE 编码转换为 Mbed TLS 编码,并从私有值计算 public 密钥。 (或者,您可以导出 TEE_ATTR_ECC_PUBLIC_VALUE
并设置 ec->Q
,但这需要更多工作。)
mbedtls_ecp_grp_id grp_id = …; // you need to convert this from the `TEE_ATTR_ECC_CURVE`
mbedtls_pk_context pk;
mbedtls_ecp_keypair *ec = malloc(sizeof(mbedtls_ecp_keypair));
mbedtls_pk_init(&pk);
mbedtls_pk_setup(&pk, mbedtls_pk_info_from_type(MBEDTLS_PK_ECDSA));
mbedtls_ecp_keypair_init(ec);
mbedtls_ecp_group_load(&ec->grp, grp_id);
mbedtls_mpi_read_binary(&ec->d, buffer, bufferlen);
mbedtls_ecp_check_privkey(&ec->grp, &ec->d);
mbedtls_ecp_mul(&ec->grp, &ec->Q, &ec->d, &ec->grp.G, mbedtls_ctr_drbg_random, &ctr_drbg);
pk->pk_ctx = ec;
完全未经测试。省略了错误检查。 ctr_drbg
是一个CTR_DRBG实例,用于计算public密钥时的致盲。
如果有 X 和 Y 可用作缓冲区,要在此处添加到已接受的答案中的代码是导入 Q 的代码。我想这些是可用的,因为为了使用 GlobalPlatform 加密 API 在 OPTEE 中创建 ECDSA 密钥,所有 4 个属性 (TEE_ATTR_xxx) 都是必需的(d、Q(X,Y) 和曲线 ID)
rc = mbedtls_mpi_read_binary(&ec->Q.X, buffer_x, buffer_x_size);
rc = mbedtls_mpi_read_binary(&ec->Q.Y, buffer_y, buffer_y_size);
rc = mbedtls_mpi_lset(&ec->Q.Z, 1);
rc = mbedtls_ecp_check_pubkey(&ec->grp, &ec->Q);
我正在使用 OPTEE-OS 和 mbedTLS 并想创建一个 CSR。我正在使用全球平台创建我的 EC 密钥 API:
res = TEE_AllocateTransientObject(
TEE_TYPE_ECDSA_KEYPAIR,
DSEC_ECDSA_SHA256_KEY_BITS,
&key_pair);
if (res != TEE_SUCCESS) {
return res;
}
然后提取私钥:
res = TEE_GetObjectBufferAttribute(
key_pair,
TEE_ATTR_ECC_PRIVATE_VALUE,
buffer,
&bufferlen);
if (res != TEE_SUCCESS) {
return res;
}
然后使用mbedTLS解析这个值并创建一个创建CSR:
mbedtls_pk_context priv_key;
mbedtls_pk_init(&priv_key);
ret = mbedtls_pk_parse_key(
&priv_key,
key,
size,
NULL ,
0
);
但是,从 TEE_GetObjectBufferAttribute 中提取的值没有页眉和页脚:
"-----BEGIN EC PRIVATE KEY-----"
"-----END EC PRIVATE KEY-----"
and 只是一个二进制数组(不是字符串)。我目前收到以下错误代码:"-15616: PK - Invalid key tag or value".
有什么方法可以只用我的私钥的二进制值创建 mbedtls_pk_context
吗?
Mbed TLS pk.h
中的解析函数需要 DER 或 PEM 输入。如果您可以找到现成的代码以从 OPTEE 中将密钥导出为 DER(或 PEM),那会更容易(但效率可能略低)。另一方面,手动导入比编写 DER 导出函数更容易。
您需要调用mbedtls_pk_setup()
声明上下文将包含ECC密钥,然后直接使用ecp.h
中的接口构建ECC密钥。将曲线名称从 TEE 编码转换为 Mbed TLS 编码,并从私有值计算 public 密钥。 (或者,您可以导出 TEE_ATTR_ECC_PUBLIC_VALUE
并设置 ec->Q
,但这需要更多工作。)
mbedtls_ecp_grp_id grp_id = …; // you need to convert this from the `TEE_ATTR_ECC_CURVE`
mbedtls_pk_context pk;
mbedtls_ecp_keypair *ec = malloc(sizeof(mbedtls_ecp_keypair));
mbedtls_pk_init(&pk);
mbedtls_pk_setup(&pk, mbedtls_pk_info_from_type(MBEDTLS_PK_ECDSA));
mbedtls_ecp_keypair_init(ec);
mbedtls_ecp_group_load(&ec->grp, grp_id);
mbedtls_mpi_read_binary(&ec->d, buffer, bufferlen);
mbedtls_ecp_check_privkey(&ec->grp, &ec->d);
mbedtls_ecp_mul(&ec->grp, &ec->Q, &ec->d, &ec->grp.G, mbedtls_ctr_drbg_random, &ctr_drbg);
pk->pk_ctx = ec;
完全未经测试。省略了错误检查。 ctr_drbg
是一个CTR_DRBG实例,用于计算public密钥时的致盲。
如果有 X 和 Y 可用作缓冲区,要在此处添加到已接受的答案中的代码是导入 Q 的代码。我想这些是可用的,因为为了使用 GlobalPlatform 加密 API 在 OPTEE 中创建 ECDSA 密钥,所有 4 个属性 (TEE_ATTR_xxx) 都是必需的(d、Q(X,Y) 和曲线 ID)
rc = mbedtls_mpi_read_binary(&ec->Q.X, buffer_x, buffer_x_size);
rc = mbedtls_mpi_read_binary(&ec->Q.Y, buffer_y, buffer_y_size);
rc = mbedtls_mpi_lset(&ec->Q.Z, 1);
rc = mbedtls_ecp_check_pubkey(&ec->grp, &ec->Q);