PHP - ECDSA - 公钥 (json) 到 Pem 格式

问题描述 投票:0回答:1

我从昨天开始就陷入困境,找不到任何方法来做我需要做的事情...... 我有一个从 API 获取的公钥 (json),我需要将其转换为 Pem 格式,因为我需要验证签名(使用 lcobucci 库) 我正在使用 PHP 5.5.9(用于我的工作)

我有这样的东西:

"kty": "EC",
"kid": "xxxxxxxxxxxx"
"use": "sig"
"crv": "P-384",
"x": "xxxxxxxxxxxxxxxxx",
"y": "xxxxxxxxxxxxxxxxx"
}

我想要这个:

-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEZe2loSV3wrroKUN/4zhwGhCqo3Xh
u1td4QjeQ5wIVR0eUu11cBFj9/nkDd+fNBs9ybqGCvfgynyn6e7NAITRnA==
-----END PUBLIC KEY-----

如果您知道如何使用 php(库)来做到这一点,那就太好了。 谢谢你;)

php public-key pem
1个回答
0
投票

晚了 4 年哈哈,但这应该有用。

300a:这是SubjectPublicKeyInfo序列的开始,表示构造序列的开始。

3003:SubjectPublicKeyInfo序列的长度,表示接下来的三个字节指定内容。

a003:这是 AlgorithmIdentifier 序列的开头,指定用于生成公钥的算法。在 ECC 中,它包括椭圆曲线的 OID(对象标识符)。

020101:这是一个 INTEGER,值为 01,表示后面的值为 OID。

300506032b6570:这是椭圆曲线的 OID。在本例中,它是 1.2.840.10045.3.1.7,对应于 prime256v1 (secp256r1) 椭圆曲线。

034200:这是实际的未压缩的 ECC 公钥。 03表示后面的值是BIT STRING,4200是BIT STRING的长度。前导 42 表示公钥由 66 个(十六进制)八位字节组成,对应于未压缩的公钥(04 前缀后跟 x 和 y 坐标)。

    $curveOID = '06082a8648ce3d030107';//'1.2.840.10045.3.1.7'; //prime256v1 CURVE NAME - CHANGE TO YOUR CURVE HEX
    $userPublicKey = base64url_decode($subscription->keys->p256dh);
    $subjectPublicKeyInfo = hex2bin('3059301306072a8648ce3d0201'.$curveOID.'034200'.bin2hex($userPublicKey));

    $pem = "-----BEGIN PUBLIC KEY-----".PHP_EOL;
    $pem .= chunk_split(base64_encode($subjectPublicKeyInfo), 64, PHP_EOL);
    $pem .= "-----END PUBLIC KEY-----";

    echo $pem.PHP_EOL.PHP_EOL;


    $userPublicKey = openssl_pkey_get_public($pem);
    if(!$userPublicKey){
        throw new Exception('Unable to compute user public key');
    }
© www.soinside.com 2019 - 2024. All rights reserved.