使用ECDSA P-256和PHP创建

时间:2018-09-07 02:24:37

标签: php cryptography jwt digital-signature xbox-one

我想知道是否可以使用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签名进行签名,如下所示:

     
      
  1. 使用带有所需私钥的ECDSA P-256 SHA-256生成JWT签名输入的UTF-8表示形式的数字签名。输出将是EC点(R,S),其中R和S是无符号整数。
  2.   
  3. 按照大端顺序将R和S转换为字节数组。每个数组长32个字节。
  4.   
  5. 将两个字节数组按R顺序,然后按S顺序连接。
  6.   
  7. Base64url编码此规范中定义的64字节数组。
  8.   

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

非常感谢您的帮助!

1 个答案:

答案 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}}。