在 Ionic 3 中使用 WebCryptoAPI 加密图像时出错

Error encrypting images with WebCryptoAPI in Ionic 3

我正在尝试使用 WebCryptoAPI 在 ionic 3 中加密图像。

我从设备的摄像头获取编码为 Base64 字符串的图像。我使用 base64-arraybuffer 库将其转换为 ArrayBuffer。 之后,我创建了一个密钥对并使用 public 密钥使用 WebCryptoAPI 进行加密。

当使用crypto.encrypt()时,代码在最后一部分失败了。我收到以下错误:

{"code":34,"name":"OperationError","message":"The operation failed for an operation-specific reason","__zone_symbol__currentTask":{"type":"microTask","state":"notScheduled","source":"Promise.then","zone":"angular","cancelFn":null,"runCount":0}}

Crypto 实现似乎只能通过接口使用,因此很难确定这个(对我来说)非常普遍的异常 - 在某个阶段我怀疑是 'zone' 错误 - 并试图将代码包装在 ngZone.run(),但无济于事。

代码运行如下:

....
import base64Arraybuffer from 'base64-arraybuffer';
declare var crypto: Crypto;
...
testCrypto() {
    // sample gif image (base64-encoded)
    const base64Image: string = "data:image/gif;base64,R0lGODlhPQ ... 0pCZbEhAAOw==";
    // convert base64 string to ArrayBuffer
    var encodedData_ab: ArrayBuffer = base64Arraybuffer.decode(base64Image);
    console.log("... arraybuffer bytelength: " + encodedData_ab.byteLength);
    // create keypair
    crypto.subtle.generateKey({
        name: "RSA-OAEP",
        modulusLength: 2048, //can be 1024, 2048, or 4096
        publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
        hash: { name: "SHA-256" }, 
    },
    true, 
    ["encrypt", "decrypt"])
    .then((keypair) => {
        console.log(keypair.publicKey);
        console.log(keypair.privateKey);
        // start encrypting data
        // ERROR occurs here >>>>
        crypto.subtle.encrypt({
            name: "RSA-OAEP"
        },
            keypair.publicKey,
            encodedData_ab
        )
        .then((buffer) => {
            console.log("... after encrypting data...")
            console.log(buffer.toString());
        });
    });
} 

ArrayBuffer 似乎存在 - 它确实显示了特定的字节长度。 密钥对对象也显示在控制台中。 Crypto 密钥对生成和加密代码基于 WebCrypto Examples

所以问题似乎与编码过程有关。任何输入将不胜感激。

好的 - 我学到了一些东西...

a Mozilla Bug Report了解到RSA加密只对小消息有效:

With RSA-OAEP the maximum message length you can encrypt is: m - 2 - 2*hLen With m=2048 and hLen=512 as in your example that is: 2048 - 2 - 2*512 = 1022 bits

当我将数据字符串 Base64Image 缩短为 254 个字符时,它起作用了...

当我找到正确的实现时我会回到这里...

---- 编辑 ----

正如所承诺的那样 - 我确实设法使用 Hybrid Crypto 解决方案实现了这一点:

  • 使用对称加密生成会话密钥和encrypt/decrypt明文
  • 使用非对称加密encrypt/decrypt 会话密钥

Charles Engelke 的 2016 workshop 是一个非常有用的资源。在实验 4 中使用 WebCypto 实现了 Hybrid Crypto 的完整实现!