I'm wondering if it's possible to properly create a signature using the P256 curve and PHP. OpenSSL in PHP has support for creating the key and getting the proper things in order.
According to this documentation - http://self-issued.info/docs/draft-jones-json-web-token-01.html#DefiningECDSA - Section 8.3 states:
A JWT is signed with an ECDSA P-256 SHA-256 signature as follows:
- Generate a digital signature of the UTF-8 representation of the JWT Signing Input using ECDSA P-256 SHA-256 with the desired private key. The output will be the EC point (R, S), where R and S are unsigned integers.
- Turn R and S into byte arrays in big endian order. Each array will be 32 bytes long.
- Concatenate the two byte arrays in the order R and then S.
- Base64url encode the 64 byte array as defined in this specification.
Herein the problem lies with getting the R and S byte arrays.
Here is an example of what I'm trying to do.
//Create Array Configuration
$config = array(
"curve_name" => "prime256v1",
"private_key_type" => OPENSSL_KEYTYPE_EC,
);
$ourkey = openssl_pkey_new($config);
/* We would get the key details to help extract out other information such as x/y coord
of curve and private key but it's not necessary to show for this part*/
// Extract the private key from $res to $privKey
openssl_pkey_export($ourkey, $privKey);
$data = "Example data we will be using to sign";
$data = hash("sha256", $data);
$signature = "";
openssl_sign($data, $signature, $privKey); // Should I include the digest algo in this call as well?
The problem here is that this signature is not R and S that I can use to concatenate together to make the real signature I need... I think.
So ultimately, is there any way I can get the R and S values from a openssl function in php?
Any help is greatly appreciated!
If you need something like JWT but not JWT in particular, consider PASETO.
Assuming you opt for v2, PASETO doesn't use ECDSA, it uses the more secure EdDSA over Ed25519. Furthermore, the standard goes out of its way to be boring so that implementations will be obviously secure.
(If you opt for v1, PASETO uses RSASSA-PSS.)
If you do need JWT in particular, look no further than lcobucci/jwt, which in turn uses PHPECC for ECDSA.
Once upon a time, PHPECC was riddled with side-channel vulnerabilities which made it a bad choice to use in production systems. These days, it's about as secure as a PHP implementation of ECDSA could be. I wrote a usability wrapper called easy-ecc if anyone wants to use PHPECC in only the safest configuration.
Luís Cobucci's JWT library is the only PHP implementation of JWT that has, to my knowledge, been formally audited by a security company. The report is public and lives here.