2013-09-16 29 views
10

Tôi bị kẹt với api mã hóa vì tôi biết rất ít về mật mã. Tôi có điều nàyXML tới PEM trong Node.js

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

Signature: 
rNbdUP-p4pEGfwQSwR6VPvAVZ-sZu-ptgw8SofYYmNTlfUB9iUbb593eCAuT5jsqDTC 

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

Tôi muốn xác minh chữ ký, làm cách nào để làm điều đó?

(Tôi đang sử dụng nút v0.10.18)

+1

Mật mã Node.js 'xác minh' chức năng dự kiến ​​khóa sẽ ở định dạng PEM. Phần phức tạp ở đây là chuyển đổi khóa XML RSA thành PEM. Tôi không thể tìm thấy bất cứ điều gì được viết bằng javascript để làm điều đó. Bạn có thể phải chuyển một số thứ như https://github.com/phpseclib/phpseclib/blob/master/phpseclib/Crypt/RSA.php#L866-922 thành javascript. –

+1

Dữ liệu gốc có phải là một tài liệu XML có chữ ký xml không? Nếu vậy, bạn sẽ cần nhiều thứ hơn để xác minh chữ ký số. Tôi đã tìm thấy một tham chiếu đến [xml-crypto] (http://architects.dzone.com/articles/check-out-digital-signature) có thể hữu ích. – pd40

+1

Dữ liệu gốc không phải là tài liệu XML có chữ ký bên trong cấu trúc của nó (như liên kết bạn đã cung cấp). – dododedodonl

Trả lời

7

Tôi không thực sự là một dev Node.js, vì vậy đây là siêu hacky .. Dưới đây là một chức năng mà nên đầu ra một RSA công cộng quan trọng PEM từ Base64 mô đun và số mũ. Tôi sẽ dựa trên nhận xét của Trevor về node.js verify mong đợi một PEM.

Chức năng này tạo cấu trúc DER ASN.1 trong hex, sau đó giải mã hex, sau đó mã hóa base64 và sau đó kẹp nó giữa -----BEGIN PRIVATE KEY----------END PRIVATE KEY-----. Xét cho cùng, đó là tất cả 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 
} 

Thao tác nhị phân bằng chuỗi hex? Yuck .. nhưng hey nó là một hack.

+0

Không làm việc cho tôi. Không rõ ràng những gì là sai tất nhiên, chỉ cần xác minh vẫn không thành công. – Aaron

+0

Sửa đổi nhẹ để làm cho mã hoạt động đúng cách. '' 'pem = '----- BEGIN PUBLIC KEY ----- \ n'; \t \t cho (var i = 0; i 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 Tôi đã chỉnh sửa câu trả lời .. sử dụng regex thay vì vòng lặp. – Tracker1

Các vấn đề liên quan