2013-09-16 7 views
10

私は暗号についてほとんど知っていないので、私は暗号APIに悩まされています。私はこれを持っていますNode.jsのPEMへのXML

XML: 
<RSAKeyValue> 
    <Modulus>1znidPBIcMcO7K/53tkTSyKqxlG5Mcws8kVtijS4tyEU4W/FEVWYpOtv+Stnb4Vt</Modulus> 
    <Exponent>AQAB</Exponent> 
</RSAKeyValue> 

Signature: 
rNbdUP-p4pEGfwQSwR6VPvAVZ-sZu-ptgw8SofYYmNTlfUB9iUbb593eCAuT5jsqDTC 

Original data: 
<xml>...some big xml...</xml> 

私は署名を確認したいのですが、どうすればいいですか?

(私はノードv0.10.18を使用しています)

+1

Node.js crypto 'verify'関数は、キーがPEM形式であることを期待しています。ここで難しいのは、RSA XMLキーをPEMに変換することです。私はそれを行うためにjavascriptで書かれた何かを見つけることができません。 javascriptにhttps://github.com/phpseclib/phpseclib/blob/master/phpseclib/Crypt/RSA.php#L866-922のようなものを移植する必要があるかもしれません。 –

+1

"元のデータ:"はXML署名付きのXML文書ですか?もしそうなら、デジタル署名を検証するために何かを必要とします。私は参考になる[xml-crypto](http://architects.dzone.com/articles/check-out-digital-signature)への参照を見つけました。 – pd40

+1

元のデータは、構造内に署名を持つXML文書ではありません(指定したリンクなど)。 – dododedodonl

答えて

7

私は本当にNode.jsのDEVないんだけど、そう、これはスーパーハック..ですここでのBase64モジュラスから出力RSA公開鍵PEMべき機能ですと指数。私は、Trevorのnode.jsに関するコメントに基づいて、verify PEMを期待しています。

この関数は、16進数でASN.1 DER構造体を作成し、16進数でデコードした後、base64でコード化した後、-----BEGIN PRIVATE KEY----------END PRIVATE KEY-----の間に挟み込みます。結局のところ、それはすべてPEMです。

function rsaPublicKeyPem(modulus_b64, exponent_b64) { 

    function prepadSigned(hexStr) { 
     msb = hexStr[0] 
     if (
      (msb>='8' && msb<='9') || 
      (msb>='a' && msb<='f') || 
      (msb>='A'&&msb<='F')) { 
      return '00'+hexStr; 
     } else { 
      return hexStr; 
     } 
    } 

    function toHex(number) { 
     var nstr = number.toString(16) 
     if (nstr.length%2==0) return nstr 
     return '0'+nstr 
    } 

    // encode ASN.1 DER length field 
    // if <=127, short form 
    // if >=128, long form 
    function encodeLengthHex(n) { 
     if (n<=127) return toHex(n) 
     else { 
      n_hex = toHex(n) 
      length_of_length_byte = 128 + n_hex.length/2 // 0x80+numbytes 
      return toHex(length_of_length_byte)+n_hex 
     } 
    } 

    var modulus = new Buffer(modulus_b64,'base64'); 
    var exponent = new Buffer(exponent_b64, 'base64'); 

    var modulus_hex = modulus.toString('hex') 
    var exponent_hex = exponent.toString('hex') 

    modulus_hex = prepadSigned(modulus_hex) 
    exponent_hex = prepadSigned(exponent_hex) 

    var modlen = modulus_hex.length/2 
    var explen = exponent_hex.length/2 

    var encoded_modlen = encodeLengthHex(modlen) 
    var encoded_explen = encodeLengthHex(explen) 
    var encoded_pubkey = '30' + 
     encodeLengthHex(
      modlen + 
      explen + 
      encoded_modlen.length/2 + 
      encoded_explen.length/2 + 2 
     ) + 
     '02' + encoded_modlen + modulus_hex + 
     '02' + encoded_explen + exponent_hex; 

    var seq2 = 
     '30 0d ' + 
      '06 09 2a 86 48 86 f7 0d 01 01 01' + 
      '05 00 ' + 
     '03' + encodeLengthHex(encoded_pubkey.length/2 + 1) + 
     '00' + encoded_pubkey; 

    seq2 = seq2.replace(/ /g,''); 

    var der_hex = '30' + encodeLengthHex(seq2.length/2) + seq2; 

    der_hex = der_hex.replace(/ /g, ''); 

    var der = new Buffer(der_hex, 'hex'); 
    var der_b64 = der.toString('base64'); 

    var pem = '-----BEGIN PUBLIC KEY-----\n' 
     + der_b64.match(/.{1,64}/g).join('\n') 
     + '\n-----END PUBLIC KEY-----\n'; 

    return pem 
} 

16進文字列を使用したバイナリ操作ですか?ヤック..しかしねえ、それはハックだ。

+0

私のために働いていません。何が間違っているのかはっきりしていません。ただ検証がまだ失敗するだけです。 – Aaron

+0

コードを適切に動作させるためにわずかな変更があります。 '' 'pem = '----- BEGIN PUBLIC KEY ----- \ n'; ; I - { \t \tするvar LEN = der_b64.length(; iはder_b64.lengthを 64){ \t \t \t LEN = 64。 \t \t \t \t pem + = der_b64.substr(i、len)+ "\ n"; \t} \t PEM + = '----- END PUBLIC KEY ----- \ n' ' – Aaron

+0

@Aaron Iは、正規表現の代わりにループを使用..回答を編集しました。 – Tracker1

関連する問題