I’m trying to create ES256 JWT using keys generated with openssl, my example works fine with RS256 keys - jwt.io verifies generated RS256 token, but not ES256. Here are code parts for RS256 generation:
mbedtls_pk_context pk_context;
mbedtls_pk_init(&pk_context);
mbedtls_pk_parse_key(
&pk_context, // The PK context to fill
private_key, // Input buffer to parse (must contain a null-terminated string)
private_key_len, // Size of the key in bytes (includes the terminating null byte)
NULL, // Optional password for decryption (if key was encrypted during generation)
0); // Size of the password in bytes
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_ctr_drbg_init(&ctr_drbg);
mbedtls_entropy_context entropy;
mbedtls_entropy_init(&entropy);
mbedtls_ctr_drbg_seed(
&ctr_drbg, // The CTR_DRBG context to seed
mbedtls_entropy_func, // The entropy callback
&entropy, // The entropy context to pass to entropy callback
NULL, // The personalization string
0); // The length of the personalization string
uint8_t md_checksum[32];
mbedtls_md(
mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), // MD algorithm
base64_header_and_payload, // Input data buffer
strlen((char*)base64_header_and_payload), // Input data length
md_checksum); // Output MD checksum
uint8_t signature[250];
size_t signature_len;
mbedtls_pk_sign(
&pk_context, // PK context to use
MBEDTLS_MD_SHA256, // Hash algorithm used
md_checksum, // Hash of the message to sign
sizeof(md_checksum), // Hash length
signature, // Place to write the signature
&signature_len, // Number of bytes written
mbedtls_ctr_drbg_random, // RNG function
&ctr_drbg); // RNG parameter
char base64_signature[250];
size_t base64_signature_len;
base64url_encode(
(const void *)signature, // Data to encode.
signature_len, // Length of data to encode.
base64_signature, // Base64 encoded data.
&base64_signature_len); // Length of base64 encoded data.
char* token = (char*)malloc(strlen((char*)base64_header_and_payload) + 1 + strlen((char*)base64_signature) + 1);
sprintf(token, "%s.%s", base64_header_and_payload, base64_signature);
For ES256 I generated pair of keys with:
openssl ecparam -name secp256r1 -genkey -noout -out ecdsa_private_key.pem
openssl ec -in ecdsa_private_key.pem -pubout -out ecdsa_public_key.pem
mbedtls_pk_get_type() added after mbedtls_pk_parse_key() returns MBEDTLS_PK_ECKEY. I’m not shure at this point that it’s correct, because there is also MBEDTLS_PK_ECDSA type, maybe I somehow need to get this one in return?
mbedtls_pk_type_t pk_type;
pk_type = mbedtls_pk_get_type(&pk_context);
Also was trying to work with ecdsa_context, added this part after mbedtls_pk_parse_key():
mbedtls_ecdsa_context ecdsa_context;
mbedtls_ecdsa_init(&ecdsa_context);
mbedtls_ecdsa_from_keypair(&ecdsa_context, pk_context.pk_ctx);
And this function instead of mbedtls_pk_sign():
mbedtls_ecdsa_write_signature(
&ecdsa_context, // PK context to use
MBEDTLS_MD_SHA256, // Hash algorithm used
md_checksum, // Hash of the message to sign
sizeof(md_checksum), // Hash length
signature, // Place to write the signature
&signature_len, // Number of bytes written
mbedtls_ctr_drbg_random, // RNG function
&ctr_drbg); // RNG parameter
It generates token in both cases, but I can’t validate it in jwt.io. Please suggest the correct way of ES256 generation with already existing private and public keys.