簡體   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