2010-08-25 120 views

回答

5

我們知道

。質子交換膜 - (增強保密郵件)的Base64編碼 DER證書,之間的 「----- BEGIN CERTIFICATE -----」 和封閉 「----- END 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-----"; 
+1

也許這是誤導性的變量名稱,但簽名值和證書(您在BEGIN/END CERTIFICATE之間放入的)是兩個不同的事情。另外,最初的問題是關於公鑰,而不是證書。在XML簽名規範中,公鑰在模數和指數之間被分割。 – Bruno 2010-08-25 16:41:28

+1

,因爲我們沒有任何有關神祕xml的信息......查看它作爲一個例子。將修改代碼以更清楚地反映 – teemitzitrone 2010-08-25 16:49:44

+0

當然,但如果它是RSAKeyValue XML DSig格式,則仍然需要重建ASN.1結構,並在將其放入base-64之前重新編碼,然後將其放入BEGIN/END PUBLIC KEY 。這不僅僅是從XML中提取文本的問題。 @馬里奧的指針會幫助。 – Bruno 2010-08-25 16:55:10

1

在XML中存儲RSA公鑰沒有標準。所以轉換的方式將取決於您擁有的XML。

+2

有一個W3C的建議,指定這個:http:// www .w3.org/TR/xmldsig-core /#sec -RSAKeyValue – Bruno 2010-08-25 16:22:16

+0

@Bruno:發表一個答案! – 2010-08-26 00:53:37

+0

@GregS,好的,我剛剛做完了。 – Bruno 2010-08-26 14:15:26

-1

也許你應該看看here

提取兩個base64編碼字符串,轉換和傳遞給PEAR :: Crypt_RSA,然後導出爲文本文件,然後OpenSSL的轉換?

Check this too

9

我假設的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公鑰結構。

在BEGIN/END PUBLIC KEY之間輸出的是什麼OpenSSL是X.509 SubjectPublicKeyInfo structure

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

subjectPublicKey由sequnce在PKCS#1 spec描述:

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 module可以從模數和指數構建RSA公共密鑰,但其toString()方法使用自定義格式(剛剛編碼的base64 PHP serialize的在陣列結構,該結構無關與ASN結果的。 1/DER編碼)。

1

這裏有一個如何在PHP讀取XML的RSA密鑰的example

0

只是爲了完整性,這裏是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_PREFIXN_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 

如果有人知道更通用的計算前綴的方法,請告訴。

相關問題