ECDSA: преобразовать двоичный открытый ключ длиной 60 байт в формат PEM для использования его с PHP openssl_verify () - PullRequest
1 голос
/ 22 октября 2019

Я хочу проверить подпись Wii в PHP. У меня есть 60 байтов открытого ключа в виде двоичных данных плюс 4 дополнительных байта. И я знаю, что это ECDSA (скорее всего, B-233). Я уже реализовал это в C, но интерпретатор PHP слишком медленный для моей реализации. Поэтому я вызываю внешний инструмент С для подтверждения подписи.

Но я хочу использовать 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-----

1 Ответ

1 голос
/ 23 октября 2019

Да, вы на правильном пути. Предполагая, что кривая известна, вы можете получить открытый ключ следующим образом (который по существу основан на идее этого ответа ):

  • В следующем,кривая NIST B-233 (он же sect233r1) предполагается, чей необработанный открытый ключ имеет размер 60 байтов. Если кривая отличается, идентификатор кривой должен быть соответственно заменен, и вместо этого должен использоваться размер открытого ключа кривой.

  • Используйте любой открытый ключ в формате 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>
    
  • Определение двоичных данных открытого ключа с помощью шестнадцатеричного редактора, например, online . На этом этапе используется тот факт, что необработанный открытый ключ расположен непосредственно в конце открытого ключа. В случае B-233 необработанный открытый ключ имеет длину 60 байтов, т.е. последние 60 байтов сгенерированного открытого ключа должны быть заменены на 60 байтов вашего текущего необработанного открытого ключа. Это искомый открытый ключ как DER, который содержит ваш необработанный открытый ключ.

  • Для процесса проверки с OpenSSL достаточно использования DER-формата, если используется опция -keyform 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-формат. Преобразование в PEM-формат проще всего, если данные DER кодируются в Base64, например, online . Наконец, вы должны добавить заголовок (-----BEGIN PUBLIC KEY-----\n) и нижний колонтитул (\n-----END PUBLIC KEY-----). Убедитесь, что сразу после заголовка и непосредственно перед нижним колонтитулом находится ровно один разрыв строки. В последнем параметре должен быть указан алгоритм хеширования, используемый для создания подписи, например:

    $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);
    
...