RSA公開鍵をXMLからPEM(PHP)に変換するにはどうすればよいですか?
6 に答える
XML形式とはXMLDSigRSAKeyValueを意味し、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.509SubjectPublicKeyInfo構造です。
SubjectPublicKeyInfo ::= SEQUENCE {
algorithm AlgorithmIdentifier,
subjectPublicKey BIT STRING }
シーケンスで構成されているsubjectPublicKey
ものは、PKCS#1仕様で説明されています。
RSAPublicKey ::= SEQUENCE {
modulus INTEGER,
publicExponent INTEGER
}
(algorithm
an AlgorithmIdentifier
)は、PKCS#1仕様(セクションA.1を参照)にも記述されています。
rsaEncryption
OBJECT IDENTIFIER ::= { pkcs-1 1 }
この構造体は、DER形式でシリアル化してから、base64でエンコードしてから、BEGIN/END区切り文字の間に配置する必要があります。
残念ながら、ASN.1 / DERエンコーディングを実行するPHPライブラリはありません(残りは比較的簡単ですが、ASN.1の処理は面倒な傾向があります)。
PHP / PEAR Crypt_RSAモジュールは、モジュラスと指数からRSA公開鍵を構築できますが、そのtoString()
メソッドはカスタム形式を使用します(serialize
配列構造でのPHPの結果のbase64エンコードのみで、ASN.1/とは関係ありません。 DERエンコーディング)。
私たちは知っています
.pem-(Privacy Enhanced Mail)Base64でエンコードされたDER証明書、「-----BEGINCERTIFICATE-----」と「-----ENDCERTIFICATE-----」で囲まれています
SignatureValue要素には、CanonicalizationMethodで指定されたアルゴリズムを適用した後、SignedInfo要素のBase64エンコード署名結果(SignatureMethod要素で指定されたパラメーターで生成された署名)が含まれます。
だから私たちは
$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-----";
PHPでXMLRSAキーを読み取る方法の例を次に示します。
RSA公開鍵をXMLで保存するための標準はありません。したがって、変換の方法は、使用しているXMLによって異なります。
完全を期すために、PythonでモジュラスからPEMを作成する実際の例を次に示します。必要に応じて、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
誰かがプレフィックスを計算するためのより一般的な方法を知っている場合は、教えてください。
多分あなたはここを見ておくべきです
2つのbase64でエンコードされた文字列を抽出し、変換してPEAR :: Crypt_RSAに渡し、テキストファイルとしてエクスポートしてから、openssl変換しますか?