乐鑫技术交流
直播中

杨福林

7年用户 1489经验值
私信 关注
[问答]

如何从ASN.1 DER编码的ECDSA签名中获取r和s?

我目前正在尝试从我的 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==

更多回帖

发帖
×
20
完善资料,
赚取积分