我想知道是否可以使用P256曲线和PHP正确创建签名。 PHP中的OpenSSL支持创建密钥并按顺序获取正确的东西。
根据本文档-http://self-issued.info/docs/draft-jones-json-web-token-01.html#DefiningECDSA-第8.3节规定:
JWT使用ECDSA P-256 SHA-256签名进行签名,如下所示:
- 使用带有所需私钥的ECDSA P-256 SHA-256生成JWT签名输入的UTF-8表示形式的数字签名。输出将是EC点(R,S),其中R和S是无符号整数。
- 按照大端顺序将R和S转换为字节数组。每个数组长32个字节。
- 将两个字节数组按R顺序,然后按S顺序连接。
- Base64url编码此规范中定义的64字节数组。
这里的问题在于获取R和S字节数组。
这是我要做的事的一个例子。
//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?
这里的问题是,这个签名不是R和S,我可以使用它们将它们串联起来以生成我需要的真实签名...我想。
因此,最终,有什么方法可以从php中的openssl函数获取R和S值吗?
非常感谢您的帮助!
答案 0 :(得分:1)
如果您需要类似 JWT的东西,而不是特别需要JWT的东西,请考虑使用PASETO。
假设您选择v2,PASETO不使用ECDSA,它使用的版本比Ed25519更安全。此外,该标准不再是boring,因此实现显然是安全的。
(如果选择v1,则PASETO使用RSASSA-PSS。)
如果您确实特别需要JWT,则只需lcobucci/jwt,它就会将PHPECC用于ECDSA。
从前,PHPECC充斥着侧通道漏洞,这使它成为在生产系统中使用的错误选择。如今,它与ECDSA的PHP实现一样安全。如果有人只想在最安全的配置中使用PHPECC,我就写了一个名为easy-ecc的可用性包装程序。
Luss Cobucci的JWT库是JWT的唯一PHP实现,据我所知,该实现已由安全公司正式审核。该报告是公开的,{@ 3}}。