[Solved] How to get r and s from an ASN.1 DER encoded ECDSA signature
Posted: Fri Jan 20, 2023 5:55 pm
Hi,
I'm currently trying to get the r and s from my ANS.1 DER signature, signed by my ATECC608B. I need these to build a 64-byte signature and base64 encode it to use in my jwt. I have attempted this, but the base-64 signature I'm getting back contains (invalid?) characters/symbols such as / and +. Here is how I'm signing my 32-byte (MBEDTLS_MD_SHA256) hash:
And this is how I'm initilizing my r and s:
And this is how I'm retrieving the 32-byte r and s respectivly:
Finally, I'm combining these and encoding them to base 64 as following:
Here is how a typical signature currently looks like (base-64 encoded):
Would appreciate any advice/pointers!
I also created an issue on github, which led me to this approach.
https://github.com/espressif/esp-idf/issues/10562
I am testing my signature at https://jwt.io/
Have a great evening!
I'm currently trying to get the r and s from my ANS.1 DER signature, signed by my ATECC608B. I need these to build a 64-byte signature and base64 encode it to use in my jwt. I have attempted this, but the base-64 signature I'm getting back contains (invalid?) characters/symbols such as / and +. Here is how I'm signing my 32-byte (MBEDTLS_MD_SHA256) hash:
Code: Select all
ret = mbedtls_pk_sign(&pkey, MBEDTLS_MD_SHA256, hash, 0, signature, MBEDTLS_MPI_MAX_SIZE, olen,
mbedtls_ctr_drbg_random, &ctr_drbg);
Code: Select all
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;
}
Code: Select all
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);
Code: Select all
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);
Code: Select all
znSBPTFzIHZ7piKsjaHWEizMi/05ygIHBhmoM+lI8aumUrv5maz9lPaG2xxynF9WO6nLGk2fwCgQReARuOTF+A==
I also created an issue on github, which led me to this approach.
https://github.com/espressif/esp-idf/issues/10562
I am testing my signature at https://jwt.io/
Have a great evening!