2016-05-17 2 views
4

Je souhaite utiliser l'API Web Cryptography sur un projet déjà existant. Pour crypter et décrypter quelque chose, je dois utiliser une CryptoKey, mais lorsque j'enregistre dans CryptoKey dans localStorage, il n'enregistre que la chaîne (CryptoKey) au lieu de l'objet.Comment enregistrer CryptoKey dans LocalStorage?

Est-il possible de sérialiser/convertir un CryptoKey dans un type simple (chaîne)?

Ma méthode de déchiffrage est

function decryptDataWithAES(keyName) 
{ 
    var decrypt_promise; 
    var aesKey = localStorage.getItem(keyName + 'key') 
    var item = localStorage.getItem(keyName) 
    var invokeVektor = localStorage.getItem(keyName + 'vector') 
    console.log("aesKey", aesKey) 

    crypto.subtle.decrypt({ name: "AES-CBC", iv: invokeVektor }, aesKey, item).then(function (result) { 
     decrypted_data = new Uint8Array(result); decrypted_data = new Uint8Array(result); 

     decrypt_promise = convertArrayBufferViewtoString(decrypted_data); 
     console.log('decryptDataWithAES ' + decrypt_promise); 
     return decrypt_promise; 
    }, 
     function(e){ 
      console.log(e.message); 
     } 
    ); 
} 

Le message d'erreur est bien sûr:

Impossible d'exécuter 'Décrypter' sur 'SubtleCrypto': paramètre 2 n'est pas de type 'CryptoKey'. 2localStorageHandler.js: 39 CryptoPromise [de CryptoKey objet]

Si je sans utiliser localStorage décrypter il n'y a aucun problème avec le cryptage des données.

Répondre

3

Envisagez d'utiliser crypto.subtle.exportKey() et crypto.subtle.importKey() avant de l'enregistrer dans localStorage, de sorte que votre code de décryptage serait comme ceci:

function decryptDataWithAES(keyName) 
{ 
    var decrypt_promise; 

    // read raw value of aesKey 
    var aesKey_RAW = localStorage.getItem(keyName + 'key') 
    var importPromise = crypto.subtle.importKey('raw', aesKey_RAW, 'AES-CBC', true, ['encrypt','decrypt']); 

    importPromise.then(function(aesKey){ 

    var item = localStorage.getItem(keyName) 
    var invokeVektor = localStorage.getItem(keyName + 'vector') 

     console.log("aesKey", aesKey) 

     crypto.subtle.decrypt({ name: "AES-CBC", iv: invokeVektor }, aesKey, item).then(function (result) { 
      decrypted_data = new Uint8Array(result); decrypted_data = new Uint8Array(result); 

      decrypt_promise = convertArrayBufferViewtoString(decrypted_data); 
      console.log('decryptDataWithAES ' + decrypt_promise); 
      return decrypt_promise; 
     }, 
      function(e){ 
       console.log(e.message); 
      } 
     ); 

    }, function(e){ console.log(e.message) }); 
} 

Pour enregistrer votre clé au format brut dans localStorage:

function saveKeyInLocalStorage(keyName, aesKey){ 
    var exportPromise = crypto.subtle.exportKey('raw',aesKey); 
    exportPromise.then(function(aesKey_RAW){ 
     localStorage.setItem(keyName + 'key' , aesKey_RAW); 
     console.log("saved."); 
    }); 
} 

Notez que les méthodes exportKey() et importKey() renvoient une promesse.

+0

J'ai toujours des problèmes avec l'exportation de la clé brute. J'appelle la fonction saveKeyInLocalStorage 'cryptoTestObject = crypto.subtle.generateKey (...) .then (fonction (clé) { saveKeyInLocalStorage (keyName, key);' et recevoir ensuite dans le exportPromise le message d'erreur dans Chrome: 'DOMException : la clé n'est pas extractible (InvalidAccessError) 'et dans Firefox' Un paramètre ou une opération n'est pas supporté par l'objet sous-jacent (InvalidAccessError) ' – AntonDerProgrammierer

0

Certaines clés ne peuvent pas être exportées au format RAW. Mais jusqu'à présent, il semble que le format JWK (json web key) est supporté partout, donc vous pouvez l'utiliser.

// to store the key: 
window.crypto.subtle.exportKey("jwk", key) 
.then(e=>localStorage.setItem("webkey",JSON.stringify(e))); 

De même, vous pouvez importer une clé() en arrière, cela dépend de l'algo de votre clé. Pour la syntaxe, voir https://github.com/diafygi/webcrypto-examples/