我目前正在尝试从我的 ANS.1 DER 签名中获取 r 和 s,由我的 ATECC608B 签名。我需要这些来构建 64 字节签名和 base64 编码以在我的 jwt 中使用。我已经尝试过这样做,但是我返回的 base-64 签名包含(无效?)字符/符号,例如
/和
+。以下是我对 32 字节 (MBEDTLS_MD_SHA256) 哈希进行签名的方式:
代码:
全选
ret = mbedtls_pk_sign(&pkey, MBEDTLS_MD_SHA256, hash, 0, signature, MBEDTLS_MPI_MAX_SIZE, olen,
mbedtls_ctr_drbg_random, &ctr_drbg);
这就是我初始化 r 和 s 的方式:
代码:
全选
unsigned char *p = (unsigned char *)signature;
const unsigned char *end = signature + *olen;
size_t len;
mbedtls_mpi r, s;
mbedtls_mpi_init(&r);
mbedtls_mpi_init(&s);
if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0)
{
ret += MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
goto cleanup;
}
if (p + len != end)
{
ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA +
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
goto cleanup;
}
if ((ret = mbedtls_asn1_get_mpi(&p, end, &r)) != 0 ||
(ret = mbedtls_asn1_get_mpi(&p, end, &s)) != 0)
{
ret += MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
goto cleanup;
}
这就是我分别检索 32 字节 r 和 s 的方式:
代码:
全选
unsigned char r_str[32];
unsigned char s_str[32];
size_t r_len = 32;
ret = mbedtls_mpi_write_binary(&r, r_str, r_len);
ret = mbedtls_mpi_write_binary(&s, s_str, r_len);
最后,我将这些组合起来并将它们编码为 base 64,如下所示:
代码:
全选
unsigned char r_s_bin[64];
size_t r_s_len = 0;
memcpy(r_s_bin, r_str, 32);
memcpy(r_s_bin + 32, s_str, 32);
unsigned char r_s_b64[2048];
size_t r_s_b64_len = 2048;
(void)atcab_base64encode((uint8_t *)r_s_bin, 64, (char *)r_s_b64, &r_s_b64_len);
ESP_LOGI(TAG, "Base64 encoded ECDSA signature (%i): %s", r_s_b64_len, r_s_b64);
这是当前典型签名的样子(base-64 编码):
代码:
全选
znSBPTFzIHZ7piKsjaHWEizMi/05ygIHBhmoM+lI8aumUrv5maz9lPaG2xxynF9WO6nLGk2fwCgQReARuOTF+A==