繁体   English   中英

ECDSA:将 60 字节的二进制公钥转换为 PEM 格式,以便与 PHP openssl_verify() 一起使用

[英]ECDSA: Convert a binary public key of 60 bytes into PEM format for using it with PHP openssl_verify()

我想在 PHP 中证明 Wii 签名。 我有 60 个字节的公钥作为二进制数据加上 4 个额外的字节。 而且我知道它是 ECDSA(很可能是 B-233)。 我已经在 C 中实现了它,但是 PHP 解释器对我的实现来说太慢了。 于是我调用了外部C工具确认签名。

但我想使用openssl_verify($data,$sig,$pubkey) 我的问题是第三个参数(公钥)。 所以我必须将 ECDSA 信息和公钥转换为可接受的格式。

有任何想法吗?

进步

我尝试了更多,并使用不同的算法创建了密钥(例如 sect233k1、sect233r1)。 我的计划是用我的密钥注入一个如此生成的公钥。 现在我收到错误消息:

error:0906D06C:PEM routines:PEM_read_bio:no start line

公钥如下所示:

-----BEGIN PUBLIC KEY-----
MFIwEAYHKoZIzj0CAQYFK4EEABoDPgAEAS+URvH1x1GXfTw6VZh8tLVPq3bgYwl8
g8OHtCKuADoZ8YayIHkJuYEqTJZBgI8YMX8FtrI8BOlBiBLF
-----END PUBLIC KEY-----

是的,你在正确的轨道上。 假设曲线是已知的,您可以按如下方式推导出公钥(这基本上是基于这个答案的想法):

  • 在下文中,假设曲线NIST B-233(又名 sect233r1)的原始公钥大小为 60 字节。 如果曲线不同,则必须相应地交换曲线 ID,并改用曲线公钥的大小。

  • 使用与您的曲线匹配的任何DER 格式的公钥。

    如果您没有,请使用 OpenSSL 创建与您的曲线匹配的 PEM 格式的私钥。 私钥具有 SEC1 格式:

     openssl ecparam -out <path to private key file> -genkey -name sect233r1 -noout

    从此私钥导出公钥为 DER。 公钥具有 X.509 格式:

     openssl ec -in <path to private key file> -pubout -outform der -out <path to public key file>
  • 使用十六进制编辑器确定公钥的二进制数据,例如 在线 在这一点上,它利用了原始公钥直接位于公钥末尾的事实。 对于 B-233,原始公钥的长度为 60 字节,即生成的公钥的最后 60 字节必须与当前原始公钥的 60 字节进行交换。 这是作为 DER 搜索的公钥,其中包含您的原始公钥。

  • 对于 OpenSSL 的验证过程,如果使用-keyform DER选项,则 DER 格式就足够了,例如

    openssl dgst -ecdsa-with-SHA1 -keyform DER -verify <path to public key file> -signature <path to signature file> <path to file for which signature is>
  • 对于 PHP 和openssl_verify中的验证过程,需要 PEM 格式。 如果 DER 数据是 Base64 编码的,例如online ,则转换为 PEM 格式是最容易的。 最后,您必须添加 header ( -----BEGIN PUBLIC KEY-----\n ) 和页脚 ( \n-----END PUBLIC KEY----- )。 请确保在 header 之后和页脚之前正好有一个换行符。 在最后一个参数中,必须指定用于创建签名的 hash 算法,例如:

     $data = hex2bin(<binary data from file for which signature is>); $signature = hex2bin(<binary data from signature file>); $pub_key_id = "-----BEGIN PUBLIC KEY-----\nMFIwEAYHKoZIzj0CAQYFK4EEABsDPgAEAfERAiIKyPaby4+efUcRmv8ucekCFMnjc6fN1IeQAO6EMcKCcFLhKRJUHijUNp0Dv/CWYLUdeN0qNOI6\n-----END PUBLIC KEY-----"; $result = openssl_verify($data, $signature, $pub_key_id, OPENSSL_ALGO_SHA1); print($result);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM