使用 PHP 使用 ECDSA P-256 SHA-256 创建 JWT

Creating a JWT With ECDSA P-256 SHA-256 With PHP

我想知道是否可以使用 P256 曲线和 PHP 正确创建签名。 PHP 中的 OpenSSL 支持创建密钥并按顺序获取正确的东西。

根据此文档 - http://self-issued.info/docs/draft-jones-json-web-token-01.html#DefiningECDSA - 第 8.3 节指出:

A JWT is signed with an ECDSA P-256 SHA-256 signature as follows:

  1. 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.
  2. Turn R and S into byte arrays in big endian order. Each array will be 32 bytes long.
  3. Concatenate the two byte arrays in the order R and then S.
  4. Base64url encode the 64 byte array as defined in this specification.

这里的问题在于获取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 值?

非常感谢任何帮助!

如果您需要类似 JWT 但不是特别需要 JWT 的东西,请考虑 PASETO

假设您选择 v2,PASETO 不使用 ECDSA,它使用比 Ed25519 更安全的 EdDSA。此外,该标准特意成为 boring,因此实施显然是安全的。

(如果您选择 v1,PASETO 使用 RSASSA-PSS。)

如果您确实特别需要 JWT,只需 lcobucci/jwt, which in turn uses PHPECC 寻找 ECDSA。

曾几何时,PHPECC 充斥着侧信道漏洞,这使得它成为生产系统中使用的一个糟糕选择。如今,它与 PHP 实施 ECDSA 一样安全。如果有人想在最安全的配置中使用 PHPECC,我写了一个名为 easy-ecc 的可用性包装器。

Luís Cobucci 的 JWT 库是唯一的 PHP JWT 实现,据我所知,它已经过安全公司的正式审计。该报告是 public,现居 here