2016-11-18 14 views
0

ユーザーがシステムからファイルを読み込み、オンザフライで暗号化してサーバーにアップロードし、反対のことを実行する必要があります(サーバーからファイルをダウンロードし、その場で解読してユーザーにローカルで保存させます)。正確な暗号方法はあまり重要ではないが、AESが好ましい。ブラウザでJavascriptを使用して任意のバイナリファイルを暗号化/復号化するにはどうすればよいですか?

リンク「Encryption/decryption of binary data in the browser」は「CryptoJSを使用する」と言っていますが、実際に動作するサンプルは見つかりませんでした。私が見つけたすべてのサンプルは文字列を扱うことに焦点を当てていましたが、バイナリデータでは無効なUnicodeシーケンスを簡単に見つけることができます。

どのような種類のファイルを処理できるテスト可能なサンプルがありますか?

答えて

1

注:データの解読方法については説明しませんが、暗号化コードと提供されたドキュメントリンクを使用することは簡単に理解できます。

まず、ユーザはinput要素を介してファイルを選択できる必要があります。

<input type="file" id="file-upload" onchange="processFile(event)"> 

その後、HTML5 FileReader API

function processFile(evt) { 
    var file = evt.target.files[0], 
     reader = new FileReader(); 

    reader.onload = function(e) { 
     var data = e.target.result; 

     // to be continued... 
    } 

    reader.readAsArrayBuffer(file); 
} 

暗号化WebCrypto APIを使用して取得したデータを使用してファイルの内容を読み込むことができます。
ランダムにキーを生成したくない場合は、crypto.subtle.importKeyを使用してください。

// [...] 
var iv = crypto.getRandomValues(new Uint8Array(16)); // Generate a 16 byte long initialization vector 

crypto.subtle.generateKey({ 'name': 'AES-CBC', 'length': 256 ]}, false, [ 'encrypt', 'decrypt' ]) 
    .then(key => crypto.subtle.encrypt({ 'name': 'AES-CBC', iv }, key, data)) 
    .then(encrypted => { /* ... */ }); 

これで、暗号化されたデータをサーバー(AJAXなど)に送信できます。 明らかにすべてを復号化するために初期化ベクトルを保存しなければなりません。


ここでは、暗号化されたデータの長さを警告する小さな例を示します。

注:それはOnly secure origins are allowedを言う場合は、httpsでページをリロードし、(これはWebCryptoのAPIの制限で)もう一度サンプルを試してみてください。 HTTPS-Link

function processFile(evt) { 
 
    var file = evt.target.files[0], 
 
     reader = new FileReader(); 
 

 
    reader.onload = function(e) { 
 
     var data = e.target.result, 
 
      iv = crypto.getRandomValues(new Uint8Array(16)); 
 
     
 
     crypto.subtle.generateKey({ 'name': 'AES-CBC', 'length': 256 }, false, ['encrypt', 'decrypt']) 
 
      .then(key => crypto.subtle.encrypt({ 'name': 'AES-CBC', iv }, key, data)) 
 
      .then(encrypted => { 
 
       console.log(encrypted); 
 
       alert('The encrypted data is ' + encrypted.byteLength + ' bytes long'); // encrypted is an ArrayBuffer 
 
      }) 
 
      .catch(console.error); 
 
    } 
 

 
    reader.readAsArrayBuffer(file); 
 
}
<input type="file" id="file-upload" onchange="processFile(event)">

+0

ありがとうございました。しかし、それは大きなファイルで動作することができますか?私のテストでは、8GB RAMマシンでChromeまたはFirefoxで500 + MBのファイルを処理することはできません。ブラウザがクラッシュします。 – Alex

+0

私は同じ問題を抱えていましたが、それを手伝ってはいけません。申し訳ありません。 – schroffl

関連する問題