【问题标题】:How to ES6 Proxy an ArrayBuffer or Uint8Array?如何 ES6 代理 ArrayBuffer 或 Uint8Array?
【发布时间】:2017-10-06 15:28:33
【问题描述】:

这些工作:

crypto.subtle.digest('SHA-512', new Uint8Array([0]))
crypto.subtle.digest('SHA-512', new Uint8Array([0]).buffer)

这些不:

crypto.subtle.digest('SHA-512', new Proxy(new Uint8Array([0]),{}))
crypto.subtle.digest('SHA-512', new Proxy(new Uint8Array([0]).buffer,{})

错误:

Failed to execute 'digest' on 'SubtleCrypto': The provided value is not of type '(ArrayBuffer or ArrayBufferView)'

instanceof Uint8Arrayinstanceof ArrayBuffer 在这两种情况下都返回 true。

【问题讨论】:

  • 看起来原生 crypto.subtle.digest 函数需要一个真正的类型化数组,而不是代理。即使它们在其他方面与 javascript 无法区分。
  • 你想做什么,为什么要在这里使用代理?
  • @Bergi,我想通过劫持它使用的任何访问方法来将文件分片传递给它。加载 1.2GB 或更大的 ArrayBuffer 会使选项卡崩溃。
  • 您可以在不使用代理的情况下完美地对文件(Blob 或 ArrayBuffer)进行切片?虽然我不确定你打算如何使用代理来降低内存使用量。
  • 原生加密不支持 .update(data) 进行散列。你给它一个ArrayBuffer,它会返回一个ArrayBuffer 的哈希值的承诺。故事结束。

标签: javascript arraybuffer webcrypto-api es6-proxy


【解决方案1】:

digest is specified by its IDL interface 只接受BufferSource,即either an ArrayBufferView or an ArrayBuffer。这种 IDL 级别的类型表示正确的实现将明确拒绝任何不具有正确内部类型的输入。

您可能想要使用Proxy 的任何技巧都无法在digest 上使用。相反,您可以在将数据传递给 digest 之前立即使用代理技巧来获得所需的确切 ArrayBuffer

例如,这里有一个代理,它伪造了一个不同于其内部对象上的bufferbufferbuffer 是正版的,所以可以传入digest,但它是由Proxy 魔术创建的:

var proxy = new Proxy(new Uint8Array([0]), {
                          get:function(obj, prop) {
                              if(prop=="buffer"){ return new Uint8Array([42]).buffer }
                              else { return obj[prop]; }
                          }
            });
crypto.subtle.digest('SHA-512', proxy.buffer)

如果无法生成缓冲区(例如,如果它太大而无法放入 RAM),那么您目前必须依赖 SubtleCrypto 以外的其他东西。

这似乎是向 W3C 提出的一个很好的观点,例如,支持 update 机制以迭代收集输入。

【讨论】:

  • 我想要的 ArrayBuffer 是非法的。因为它太大了。
  • @MihailMalostanidis 那么你可能不走运。您可能需要查看是否可以使用支持增量更新的非本地实现。这似乎是向 W3C 提出的一个很好的观点。此外,对于某些散列,可能会进行增量更新(例如,this Crypto.SE post 暗示您可以自己编写一些组合函数F,以便 F(Hash(s1), s2) == Hash(s1 + s2) 用于 SHA-1、-2 和 -3) ,但您需要咨询哈希专家来创建这样的函数,如果它存在于给定的哈希算法中。
  • @MihailMalostanidis 所以看起来 F(oldHash, newInput) 这样的函数对于 SHA-1 和 SHA-2 系列函数(包括 512)是可能的,但对于 SHA-3 系列函数是不可能的。请参阅en.wikipedia.org/wiki/Length_extension_attack 了解如何开始实现这样的功能。
  • 在使用纯 js 解决方案之前,我正在考虑这样做 (H(F(H(s1),s2)。然而,即使它可以击败一次迭代的填充,必须将状态加载到 SHA-512 机器中意味着本机函数将无法再次工作。
  • 也许我应该考虑在wasm中做,它现在在移动设备上支持(这是纯js伤害最大的地方)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-09-27
  • 2020-04-26
  • 2019-05-19
  • 1970-01-01
  • 1970-01-01
  • 2023-03-11
  • 1970-01-01
相关资源
最近更新 更多