2014-11-04 123 views
3

加密的文件,我有問題的文件進行加密與SJCL和JavaScript。與SJCL客戶端

我設法使用FileReader API和readAsBinaryString加密文本文件。 當涉及到加密PDF/PNG/..然後問題可能是由於編碼。

我發現我可以使用完全適合這個任務的readAsArrayBuffer,所以我基本上讀取文件並創建與new Uint8Array()新類型的數組,但我不知道我應該如何加密這樣的數據。

這裏是我的代碼:

/** Convert from an array of bytes to a bitArray. */ 
function toBitArrayCodec(bytes) { 
    var out = [], i, tmp=0; 
    for (i=0; i<bytes.length; i++) { 
     tmp = tmp << 8 | bytes[i]; 
     if ((i&3) === 3) { 
      out.push(tmp); 
      tmp = 0; 
     } 
    } 
    if (i&3) { 
     out.push(sjcl.bitArray.partial(8*(i&3), tmp)); 
    } 
    return out; 
} 

/** Convert from a bitArray to an array of bytes. */ 
function fromBitArrayCodec(arr) { 
    var out = [], bl = sjcl.bitArray.bitLength(arr), i, tmp; 
    for (i=0; i<bl/8; i++) { 
     if ((i&3) === 0) { 
      tmp = arr[i/4]; 
     } 
     out.push(tmp >>> 24); 
     tmp <<= 8; 
    } 
    return out; 
} 

var reader = new FileReader(); 
    reader.readAsArrayBuffer(fileData); //filedata comes from function 
    reader.onload = function() { 
     var bytes = new Uint8Array(reader.result); 
     var bits = toBitArrayCodec(bytes); 
     var crypt = sjcl.encrypt("aaaaa", bits); 

     var decrypt = sjcl.decrypt("aaaaa", crypt); 
     var byteNumbers = fromBitArrayCodec(decrypt); 
     var byteArray = new Uint8Array(byteNumbers); 
     saveData(byteArray, 'png.png'); 

我對

Uncaught URIError: URI malformed sjcl.js:12sjcl.codec.utf8String.fromBits sjcl.js:12sjcl.json.decrypt sjcl.js:44reader.onload 

我需要知道如何加密uint8array或另一種選擇如何加密(PDF/PNG/..)文件得到錯誤。

+0

在哪一行會拋出錯誤?我懷疑你解密時會發生這種情況。 – 2014-11-04 12:12:46

+0

是的,它發生在sjcl.decrypt – Yetti 2014-11-04 20:38:51

回答

2

sjcl中的純文本預計爲utf8編碼。加密手動構建的bitArray的作品,因爲加密是在bitArray上完成的,它不需要解碼。但是在解密的最後是一個編碼步驟,它將恢復的明文bitArray轉換爲utf8string。這不起作用,因爲它包含不可打印的字符,因爲源可能是二進制的。

解決方法是在加密之前將其編碼爲Base64,並在解密後將其轉換回來。

var bytes = new Uint8Array(reader.result); 
var bits = toBitArrayCodec(bytes); 
var base64bits = sjcl.codec.base64.fromBits(bits); // added 
var crypt = sjcl.encrypt("aaaaa", base64bits); 

var base64decrypt = sjcl.decrypt("aaaaa", crypt); 
var decrypt = sjcl.codec.base64.toBits(base64decrypt); // added 
var byteNumbers = fromBitArrayCodec(decrypt); 
var byteArray = new Uint8Array(byteNumbers); 
+0

yeeeey,感謝buddy救了我的一天:) – Yetti 2014-11-04 21:02:09