Преобразование открытого ключа RSA, от XML до PEM (PHP)

Как преобразовать открытый ключ RSA, от XML до PEM (PHP)?

мы знаем

.pem – (конфиденциальная расширенная почта). Сертификат DER с кодировкой Base64, заключенный между «—– BEGIN CERTIFICATE —–» и «—– КОНЕЦ СЕРТИФИКАТА —–»

X.509

Элемент SignatureValue содержит результат подшивки Base64 – подпись, сгенерированную с параметрами, указанными в элементе SignatureMethod, – элемента SignedInfo после применения алгоритма, указанного в методе CanonicalizationMethod.

XML_Signature

поэтому мы заканчиваем

$xml = simplexml_load_file($xmlFile); // or simplexml_load_string $pem = "-----BEGIN CERTIFICATE-----\n"; $pem .= $xml->SignatureValue; $pem .= "\n-----END CERTIFICATE-----"; // save to file 

если ваш XML-файл не является XML_Signature

 $xml = simplexml_load_file($xmlFile); // or simplexml_load_string $pem = "-----BEGIN CERTIFICATE-----\n"; $pem .= $xml->nodeWithWantedValue; // use base64_encode if needed $pem .= "\n-----END CERTIFICATE-----"; 

Я предполагаю, что в формате XML вы подразумеваете XML DSig RSAKeyValue , а в формате PEM вы подразумеваете, что OpenSSL экспортирует между -----BEGIN PUBLIC KEY----- и -----END PUBLIC KEY----- .

Сначала вам нужно извлечь модуль и публичный экспонент из XML.

  <RSAKeyValue> <Modulus>xA7SEU+e0yQH5rm9kbCDN9o3aPIo7HbP7tX6WOocLZAtNfyxSZDU16ksL6W jubafOqNEpcwR3RdFsT7bCqnXPBe5ELh5u4VEy19MzxkXRgrMvavzyBpVRgBUwUlV 5foK5hhmbktQhyNdy/6LpQRhDUDsTvK+g9Ucj47es9AQJ3U= </Modulus> <Exponent>AQAB</Exponent> </RSAKeyValue> 

Вы можете легко преобразовать их в битовую строку, используя base64_decode .

Как только это будет сделано, вам необходимо как-то создать структуру открытого ключа ASN.1 .

Экспорт OpenSSL между BEGIN / END PUBLIC KEY представляет собой структуру X.509 SubjectPublicKeyInfo .

 SubjectPublicKeyInfo ::= SEQUENCE { algorithm AlgorithmIdentifier, subjectPublicKey BIT STRING } 

subjectPublicKey сделан из sequnce описан в спецификации PKCS # 1 :

 RSAPublicKey ::= SEQUENCE { modulus INTEGER, publicExponent INTEGER } 

algorithm ( AlgorithmIdentifier ) также описан в спецификации PKCS # 1 (см. Раздел A.1):

 rsaEncryption OBJECT IDENTIFIER ::= { pkcs-1 1 } 

Эта структура должна быть сериализована в форме DER, затем закодирована base64, а затем помещена между разделителями BEGIN / END.

К сожалению, я не знаю какой-либо библиотеки PHP для кодирования ASN.1 / DER (остальное относительно просто, но работа с ASN.1 имеет тенденцию быть утомительной).

Модуль PHP / PEAR Crypt_RSA может создавать открытые ключи RSA от модуля и экспоненты, но его метод toString() использует настраиваемый формат (только base64-кодирование результата serialize PHP в структуре массива, что не имеет ничего общего с ASN.1 / DER).

Нет стандарта для хранения открытых ключей RSA в XML. Таким образом, способ преобразования будет зависеть от XML, который у вас есть.

Вот пример того, как читать XML-ключи RSA в PHP:

Просто для полноты, вот рабочий пример создания PEM из модуля в python. Вы можете вызвать его в подпроцессе из PHP, если это необходимо.

Мясо раствора:

 def big_endian(n): s = '%x' % n if len(s) & 1: s = '0' + s return s.decode('hex') from M2Crypto import RSA e = E_PREFIX + big_endian(public_exponent) n = N_PREFIX + big_endian(modulus) new = RSA.new_pub_key((e,n)) new.save_key('foo.pub') 

Где E_PREFIX и N_PREFIX – это константы, которые (насколько я могу судить) зависят от экспоненты и длины ключа. Вот краткая таблица, которую я построил:

 E_PREFIX = '\x00\x00\x00\x01' # 0x3 (3) E_PREFIX = '\x00\x00\x00\x03' # 0x10001 (65537) N_PREFIX = '\x00\x00\x00!\x00' # 256-bit N_PREFIX = '\x00\x00\x00A\x00' # 512-bit (default) N_PREFIX = '\x00\x00\x00\x81\x00' # 1024-bit N_PREFIX = '\x00\x00\x01\x01\x00' # 2048-bit N_PREFIX = '\x00\x00\x02\x01\x00' # 4096-bit 

Если кто-то знает более общий способ вычисления префиксов, скажите.

Может быть, вы должны посмотреть здесь

Извлеките две строки, закодированные в base64, конвертируйте и перейдите в PEAR :: Crypt_RSA, затем экспортируйте в текстовый файл, затем openssl convert?

Проверьте это тоже