x509certificate — Как подписать сертификат X.509 с RS256 на PHP? Не удалось получить действительный отпечаток пальца … x5t

Я реализовал библиотеку генератора токенов JWT из Вот, и я могу получить токен RS256 (полезная нагрузка).
Но у меня проблема с данными заголовка:
Мне нужно одно значение заголовка «x5t», которое не генерируется из данной библиотеки.
Мне нужны данные заголовка, такие как:

{
"typ": "JWT",
"alg": "RS256",
"x5t": "COm8ON2SD2MTc5jwcxZ0vE3-XJo"}

Я получаю первые два параметра успешно, но не могу получить действительный третий параметр.

Мой пример кода:

$fingerprint = str_replace("SHA1 Fingerprint=", '', system('openssl x509 -noout -in my.pem -fingerprint'));
$fingerprint = sha1($fingerprint);
$fingerprint = base64_encode($fingerprint);
$fingerprint = rtrim(strtr($fingerprint, "+/", "-_"), '=');

Чтобы сгенерировать действительный параметр «x5t», в .NET уже есть код, который необходимо преобразовать в PHP.

Спасибо за просмотр моего вопроса.
Любое предложение приветствуется.

1

Решение

Если у вас PHP 5.6, вы можете использовать следующую функцию openssl_x509_fingerprint:

$cert = openssl_x509_read($certificate);
$sha1_hash = openssl_x509_fingerprint($cert); // sha1 hash (x5t parameter)
$sha256_hash = openssl_x509_fingerprint($cert, 'sha256'); // sha256 hash (x5t#256 parameter)

Если у вас нет PHP 5.6, вы можете сгенерировать этот отпечаток самостоятельно, используя содержимое файла сертификата (начинается с BEGIN CERTIFICATE и заканчивается END CERTIFICATE):

function sha1_thumbprint($file_content)
{
$file_content = preg_replace('#-.*-|\r|\n#', '', $file_content);
$bin = base64_decode($file_content);
return hash('sha1', $bin);
}

Не забудьте зашифровать в Base64 Url Safe результат.

$encoded_fingerprint = rtrim(strtr(base64_encode($fingerprint), "+/", "-_"), '=');
1

Другие решения

system выводит свой результат напрямую, если вы не используете необязательный второй параметр, который помещает результат в переменную.

Так что используйте

system('openssl x509 -noout -in my.pem -fingerprint', $sha1);
$fingerprint = str_replace("SHA1 Fingerprint=", '', $sha1);

http://php.net/manual/en/function.system.php

0

openssl_x509_fingerprint (который упомянул Флорент Морселли) возвращает хэш sha1 кодировки DER для сертификата. например.

<?php
$cert = '...';

echo openssl_x509_fingerprint($cert);
echo "\r\n<br />\r\n";
echo sha1(base64_decode(preg_replace('#-.*-|\r|\n#', '', $cert)));

Они выводят одно и то же. По крайней мере, с этим сертификатом:

-----BEGIN CERTIFICATE-----
MIIDITCCAoqgAwIBAgIQT52W2WawmStUwpV8tBV9TTANBgkqhkiG9w0BAQUFADBM
MQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkg
THRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBDQTAeFw0xMTEwMjYwMDAwMDBaFw0x
MzA5MzAyMzU5NTlaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh
MRYwFAYDVQQHFA1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKFApHb29nbGUgSW5jMRcw
FQYDVQQDFA53d3cuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC
gYEA3rcmQ6aZhc04pxUJuc8PycNVjIjujI0oJyRLKl6g2Bb6YRhLz21ggNM1QDJy
wI8S2OVOj7my9tkVXlqGMaO6hqpryNlxjMzNJxMenUJdOPanrO/6YvMYgdQkRn8B
d3zGKokUmbuYOR2oGfs5AER9G5RqeC1prcB6LPrQ2iASmNMCAwEAAaOB5zCB5DAM
BgNVHRMBAf8EAjAAMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwudGhhd3Rl
LmNvbS9UaGF3dGVTR0NDQS5jcmwwKAYDVR0lBCEwHwYIKwYBBQUHAwEGCCsGAQUF
BwMCBglghkgBhvhCBAEwcgYIKwYBBQUHAQEEZjBkMCIGCCsGAQUFBzABhhZodHRw
Oi8vb2NzcC50aGF3dGUuY29tMD4GCCsGAQUFBzAChjJodHRwOi8vd3d3LnRoYXd0
ZS5jb20vcmVwb3NpdG9yeS9UaGF3dGVfU0dDX0NBLmNydDANBgkqhkiG9w0BAQUF
AAOBgQAhrNWuyjSJWsKrUtKyNGadeqvu5nzVfsJcKLt0AMkQH0IT/GmKHiSgAgDp
ulvKGQSy068Bsn5fFNum21K5mvMSf3yinDtvmX3qUA12IxL/92ZzKbeVCq3Yi7Le
IOkKcGQRCMha8X2e7GmlpdWC1ycenlbN0nbVeSv3JUMcafC4+Q==
-----END CERTIFICATE-----

openssl_x509_fingerprint только на PHP 5.6, поэтому, если вы PHP 5.5 или более ранней версии, вы можете использовать альтернативный метод.

0
По вопросам рекламы [email protected]