0

Je souhaite vérifier un message signé CMS avec l'API Webcrypto JavaScript. Le message fait partie d'une réponse d'horodatage selon RFC 3161.Impossible de vérifier un message signé CMS avec l'API Webcrypto

Wireshark display

Je prends la signature, le contenu (de encapContentInfo) et la clé publique et le transmettre à la fonction suivante qui importe la clé et vérifie la signature:

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); 
    }); 
} 

la sortie est la suivante:

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

Comme vous pouvez le voir, la vérification fa ils, mais je suis assez sûr que la signature est valide car ce serveur d'horodatage est utilisé par beaucoup de gens.

Y at-il un problème avec ma mise en œuvre? J'essaie de faire cela à l'intérieur d'une extension Firefox.

Modifier: Il semble qu'il soit nécessaire d'utiliser la valeur DER du champ signedAttrs, de le hacher puis de le vérifier avec le certificat.

Répondre

0

J'ai réussi à le faire moi-même: vous devez d'abord déchiffrer la signature avec la clé publique pour obtenir un objet ASN.1 qui contient le résumé du message.

par exemple. openssl rsautl -inkey cert.pem -pubin -in signature -out out

message digest object

Ensuite vous prenez le signedAttrs objet et remplacer l'étiquette explicite au début (0xA0) avec la balise set (0x31) en raison de la phrase suivante dans la RFC:

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

Ensuite, vous calculez un résumé (avec le même algorithme que dans digestAlgorithm dans signerInfo) de l'objet set.

Les deux valeurs de résumé sont les mêmes si la signature est valide.