- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在尝试编写一个应用程序,以在浏览器中使用 JS 对文件进行端到端加密。但是我似乎无法正确解密所有文件。
TL;DR 由于整体加密大于 1MB 的文件是不切实际的,因此我尝试逐 block 加密它们。这样做之后,我尝试将加密的单词(由 CryptoJS
的 WordArray 产生)写入一个 blob。至于解密,我读取文件并根据加密 block 时生成的映射将它们拆分为 block 并尝试解密它们。问题是解密结果是0位!
我想我在正确解密时没有读取 block 。请查看下面的函数 getBlob
(将数据写入 blob)的代码和用于读取 block 的 decryptFile
的最后一部分。
更多解释
我使用默认设置的 CryptoJS AES。
现在我的代码是这样的:
function encryptFile (file, options, resolve, reject) {
if (!options.encrypt) {
return resolve(file)
}
if (!options.processor || !options.context) {
return reject('No encryption method.')
}
function encryptBlob (file, optStart, optEnd) {
const start = optStart || 0
let stop = optEnd || CHUNK_SIZE
if (stop > file.size - 1) {
stop = file.size
}
const blob = file.slice(start, stop)
const fileReader = new FileReader()
fileReader.onloadend = function () {
if (this.readyState !== FileReader.DONE) return
const index = Math.ceil(optStart / CHUNK_SIZE)
const result = CryptoJS.lib.WordArray.create(this.result)
encryptedFile[index] = encrypt(result)
chunksResolved++
if (chunksResolved === count) {
const {sigBytes, sigBytesMap, words} = getCipherInfo(encryptedFile)
const blob = getBlob(sigBytes, words)
resolve(blob, Object.keys(sigBytesMap))
}
}
fileReader.readAsArrayBuffer(blob)
}
let chunksResolved = 0
const encryptedFile = []
const CHUNK_SIZE = 1024*1024
const count = Math.ceil(file.size / CHUNK_SIZE)
const encrypt = value => options.processor.call(
options.context, value, 'file',
(v, k) => CryptoJS.AES.encrypt(v, k))
for (let start = 0; (start + CHUNK_SIZE) / CHUNK_SIZE <= count; start+= CHUNK_SIZE) {
encryptBlob(file, start, start + CHUNK_SIZE - 1)
}
}
如您所见,我正在尝试逐 block 读取文件(每个 block 为 1MB 或 fileSize % 1MB
)作为 ArrayBuffer,将其转换为 WordArray 以便 CryptoJS 理解和加密它。
在加密所有 block 后,我尝试将它们必须的每个单词写入一个 blob(使用我在 Google Code 的 CryptoJS 问题中找到的代码,如下所述)并且我想这是哪里出了问题 .我还为加密 block 的结束位置生成了一个映射,以便稍后可以使用它从二进制文件中获取 block 以进行解密。
下面是我解密文件的方式:
function decryptFile (file, sigBytesMap, filename, options, resolve, reject) {
if (!options.decrypt) {
return resolve(file)
}
if (!options.processor || !options.context) {
return reject('No decryption method.')
}
function decryptBlob (file, index, start, stop) {
const blob = file.slice(start, stop)
const fileReader = new FileReader()
fileReader.onloadend = function () {
if (this.readyState !== FileReader.DONE) return
const result = CryptoJS.lib.WordArray.create(this.result)
decryptedFile[index] = decrypt(result)
chunksResolved++
if (chunksResolved === count) {
const {sigBytes, words} = getCipherInfo(decryptedFile)
const finalFile = getBlob(sigBytes, words)
resolve(finalFile, filename)
}
}
fileReader.readAsArrayBuffer(blob)
}
let chunksResolved = 0
const count = sigBytesMap.length
const decryptedFile = []
const decrypt = value => options.processor.call(
options.context, value, 'file',
(v, k) => CryptoJS.AES.decrypt(v, k))
for (let i = 0; i < count; i++) {
decryptBlob(file, i, parseInt(sigBytesMap[i - 1]) || 0, parseInt(sigBytesMap[i]) - 1)
}
}
解密与加密完全一样,但不起作用。虽然 block 不再是 1MB,但它们仅限于 map 中提到的 sigBytes。解密无结果! sigBytes: 0
.
下面是生成 blob 和获取 sigbytesMap 的代码:
function getCipherInfo (ciphers) {
const sigBytesMap = []
const sigBytes = ciphers.reduce((tmp, cipher) => {
tmp += cipher.sigBytes || cipher.ciphertext.sigBytes
sigBytesMap.push(tmp)
return tmp
}, 0)
const words = ciphers.reduce((tmp, cipher) => {
return tmp.concat(cipher.words || cipher.ciphertext.words)
}, [])
return {sigBytes, sigBytesMap, words}
}
function getBlob (sigBytes, words) {
const bytes = new Uint8Array(sigBytes)
for (var i = 0; i < sigBytes; i++) {
const byte = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff
bytes[i] = byte
}
return new Blob([ new Uint8Array(bytes) ])
}
我猜问题出在我用来读取加密 block 的方法上。或者写出来!
我还应该提一下,之前我在加密方面做了一些不同的事情。我使用 toString
方法和默认编码(我认为是 CryptoJS.enc. Hex
) 但有些文件没有正确解密。它与原始文件的大小无关,而与它们的类型无关。同样,我在猜测!
最佳答案
原来问题是 CryptoJS.AES.decrypt(value, key)
返回的 WordArray
有 4 个额外的单词作为填充,不应包含在最后的单词中结果。 CryptoJS 尝试取消填充结果,但仅相应地更改 sigBytes
而不会更改 words
。所以在解密时,在将 block 写入文件之前弹出那些额外的单词。 4 个词表示完整的词 block ,3 个词表示较小的词 block (最后一个词 block )。
关于javascript - CryptoJS - 解密加密文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40848757/
我想在我的 AngularJS 应用程序中使用 CryptoJS,但我收到此错误:找不到变量:CryptoJS。 我将其包含在我的 index.html 中: 并尝试加密一些东西: var encr
这是我的 Anguarjs 代码 $httpProvider.defaults.headers.common['key'] = CryptoJS.AES.encrypt('', '=', {
我正在尝试在 CryptoJS 上解密并在 PyCrypto 上加密。 我看到 this 一个很好的答案,就像魅力一样,唯一的问题是它调整 PyCrypto 以与 CryptoJS 一起工作,我更喜欢
我正在尝试使用 CryptoJS AES,如下所示: var msg = "café"; var key = "something"; var c = CryptoJS.AES.encrypt(msg
我需要解密用 CryptoJS 加密的东西。我有用于加密的函数、加密对象的结构和用于加密的数据,但我需要知道该对象的一些值。 函数是: var c = CryptoJS.enc.Utf8.parse(
我正在使用 CryptoJS 手动解密具有一组提供的值的字符串。提供了 secret ,然后采用 SHA256。消息和初始化向量是 base 64 编码的。这就是我正在尝试的,但每次我运行它时,输出都
我有一个包含 SHA1 散列数据的密码表。所以我想用 CryptoJS 进行验证输入。它出错了..但是当我尝试显示它时,结果匹配..我编写了错误的函数吗? 这是我的代码 function checkC
我想使用类似于 SpeakEasy 的 javascript 创建一个 HOTP 客户端 上面的库是为服务器端 javascript 使用而设计的,它使用了 NodeJS。 我想在浏览器的前端 jav
我正在尝试编写一个应用程序,以在浏览器中使用 JS 对文件进行端到端加密。但是我似乎无法正确解密所有文件。 TL;DR 由于整体加密大于 1MB 的文件是不切实际的,因此我尝试逐 block 加密它们
我想连接到蓝牙设备。通信仅通过十六进制字符串。我需要编码一个 16 字节的值。因此,我还期望有一个 16 字节的值。在我的实现中,CryptoJS 总是返回更长的结果。根据文档,不需要 IV。 (“所
我在使用 CryptoJS 时遇到问题。 我尝试加密字符串,但它给出了不同的输出。 字符串:“测试消息” key :“123456” 这是我尝试运行的测试代码 var encrypted =
我正在尝试使用 CryptoJS 加密 32 个字符的字符串: var string = '12345678901234567890123456789012'. 我使用 AES256 的 32 个字符
我需要解密 JavaScript 中的十六进制消息,其结果与用 Java 编写的代码完全相同。然而,使用 CryptoJs 的 Javascript 版本返回一个空结果 Java中的代码: priva
我无法使用 jQuery 访问 encryptedData 变量,但在 alert 中它可以工作!!! $( document ).ready(function() { var te
我已经为 RSASHA256 编写了 javascript,但出现错误 crypto.js 未定义。 function aaa(message,secret) { ; ;
我正在尝试使用 CryptoJS 的 PBKDF2 和盐散列来存储我的密码。这是我对注册中的用户密码进行哈希处理的部分: var passwordInput = document.getElement
我正在学习各种哈希技术,并发现了有趣的库,从 cryptoJs 开始 在文档中,有多个选项定义如下散列哈马卡PBKDF2密码编码器 我理解散列是关于生成密文。 HMAC 的作用是生成消息验证代码。但我
我已经使用以下库很多年了,现在它不可用了。 http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/md5.js 有人可以帮忙寻找替代
我已经使用以下库很多年了,现在它不可用了。 http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/md5.js 有人可以帮忙寻找替代
我正在尝试将Node.js脚本 转换为Golang。但是,我在解码Base64时总是收到"error: illegal base64 data at input byte 40"错误。有人可以帮我,已
我是一名优秀的程序员,十分优秀!