0

Ich möchte eine CMS signierte Nachricht mit der JavaScript webcrypto API überprüfen. Die Nachricht ist ein Teil einer Zeitstempel-Antwort nach RFC 3161.Kann eine CMS signierte Nachricht mit webcrypto API nicht überprüfen

Wireshark display

So nehme ich die Unterschrift, den Gehalt (aus encapContentInfo) und dem öffentlichen Schlüssel und gibt sie an die folgenden Funktion, die den Schlüssel importiert und die Signatur verifiziert:

function verify(signature, data, publicKey, callback) { 

    console.log("pubkey: " + publicKey); 
    console.log("data: " + data); 
    console.log("signature: " + signature); 

    crypto.subtle.importKey(
    "spki", 
    new Uint8Array(hexToArray(publicKey)), 
    { 
     name: "RSASSA-PKCS1-v1_5", 
     hash: {name: "SHA-1"} 
    }, 
    false, 
    ["verify"] 
    ) 
    .then(function(publicKey){ 

     console.log(publicKey); 

     crypto.subtle.verify(
     { 
      name: "RSASSA-PKCS1-v1_5", 
      hash: {name: "SHA-1"} 
     }, 
     publicKey, 
     new Uint8Array(hexToArray(signature)), 
     new Uint8Array(hexToArray(data)) 
     ) 
     .then(function(isvalid){ 
      console.log("valid: " + isvalid); 
     }) 
     .catch(function(err){ 
      throw(err); 
     }); 

    }) 
    .catch(function(err){ 
     throw(err); 
    }); 
} 

der Ausgang ist die folgende:

pubkey: 30820122300d06092a864886f70d01010105000382010f003082010a0282010100a9ac33b296da7177999d464f47aa4a40d57d58dcfd93beae68913ab75cb77fe36c4b52b3b55a53cce10f70880a81aba4ffdc1d4826fe645cbabcd1e0b4eceff702f6fb378670128eadbe39a4a9e484c1d01f95fcfcbd44ca091dcc344e0356ca8967f54f7f6acc0dd5af8c1a4f77003fe01c3b98d6611d52b3fe432962544e142cc6f99163ccb7798bb8d4aea948d0cd6f72b740915b87ca2824ac9ec958ab0e5eacb36a7a66be091e826f862849026aa911e3b1a84487f6654aad7f3be4d1d9d312b2f9fcd7c69836ae893060393a47b310a6a4b03eeea6c8659df57782fa75855007d5ffb622ff8d229edd57c0771149b7fc827780fcde0c02f82bc2977d250203010001 
data: 306b020101060c2b0601040181ad21822c16013031300d0609608648016503040201050004201b14e43e38297d534d827e351c15347f9eebc973258c8b555c044de46c5a0f02021424e3f636950c119fb3ebdb289d60d7bc637f3bd9180f32303136303431393139333931395a 
signature: 7a65069868d97fb0ffcd53bca6b80daa671e1b0ac1a1d262ba2fba1525d0ca8e4998d4f49cba990f9a89c52003457ca1bbb037dee8e5e64c617af0c1ea72215b648477b052165810f4f6eb7f869ac19373b2aad1a2b5a809b8b758bdad540a5cd1f33d3c80870c7ae9c6db61dd7c7f8c346ee3c7aadc16f90ed87833a4ba771cbdc930a6dfb3fd16f5ab57de212deddc4d49c11ef825a8d996ba40e0e07c7c5788000d61169fe7512c97d29f7ff4b8ce2842e5b339dae5cef1eb517457b3e8b98bc887dda952b6346bd8345e5eb2cdd976fe5688d375551bc2a20cd7aafd1bbf6a9d102ad2a8dea620ad3ed6763f0841ec020dc1ad485ed1448ae5f5d511ef8f 
CryptoKey {} 
valid: false 

Wie Sie sehen können, die Überprüfung fa Ich bin mir ziemlich sicher, dass die Signatur gültig ist, da dieser Zeitstempelserver von vielen Leuten benutzt wird.

Ist irgendetwas mit meiner Implementierung falsch?

Ich versuche, dies innerhalb einer Firefox-Erweiterung zu tun.

Bearbeiten: Es scheint, dass es erforderlich ist, den DER-Wert des signedAttrs-Felds zu verwenden, es zu hashen und es dann mit dem Zertifikat zu überprüfen.

Antwort

0

Ich habe es geschafft, es selbst zu tun: Sie müssen zuerst die Signatur mit dem öffentlichen Schlüssel entschlüsseln, um ein ASN.1-Objekt zu erhalten, das den Nachrichtenauszug enthält.

z.B. openssl rsautl -inkey cert.pem -pubin -in signature -out out

message digest object

Dann nehmen Sie die signedAttrs Objekt und den expliziten Tag am Anfang (0xA0) mit dem Set-Tag (0x31) wegen des folgenden Satzes in der RFC ersetzen:

The IMPLICIT [0] tag in the signedAttrs is not used for the DER encoding, rather an EXPLICIT SET OF tag is used 

Dann berechnen Sie einen Digest (mit dem gleichen Algorithmus wie in DigestAlgorithm in SignerInfo) des Set-Objekts.

Die zwei Digest-Werte sind identisch, wenn die Signatur gültig ist.

Verwandte Themen