【问题标题】:Wrapping symmtric key with public RSA key causes DOMException (InvalidAccessError)使用公共 RSA 密钥包装对称密钥会导致 DOMException (InvalidAccessError)
【发布时间】:2021-03-11 16:04:49
【问题描述】:

我正在尝试使用 Web Crypto API 包装对称密钥,但出现错误: DOMException: key.usages does not permit this operation

对于使用 Web Crypto API 还是很陌生,所以我不完全理解为什么这是一个问题。我想用公钥包装对称密钥,然后用我的私钥解开它。

我把问题提取到一个小代码沙箱https://codesandbox.io/s/cranky-driscoll-v0itr?file=/src/index.ts

或者,可以使用以下步骤来重现问题。

  • 生成加密密钥对(我在这里使用了 RSA)

  • 生成对称密钥

  • 打电话

    window.crypto.subtle.wrapKey(
        "raw",
        fileKey,
        publicKey,
        publicKey.algorithm.name
    );
    

这是沙盒中的完整代码:

sync function foo() {
  try {
    const cryptoKeyPair = await window.crypto.subtle.generateKey(
      {
        name: "RSA-OAEP",
        modulusLength: 4096,
        publicExponent: new Uint8Array([1, 0, 1]),
        hash: "SHA-256"
      },
      true,
      ["encrypt", "decrypt"]
    );
    const publicKey = cryptoKeyPair.publicKey;

    const fileKey = await window.crypto.subtle.generateKey(
      { name: "AES-GCM", length: 256 },
      true,
      ["encrypt", "decrypt"]
    );

    const wrapKeyResult = await window.crypto.subtle.wrapKey(
      "raw",
      fileKey,
      publicKey,
      publicKey.algorithm.name
    );
    // ^^ here we get error: DOMException: key.usages does not permit this operation
    /** 
    * {
    *  code: 15
    *  message: "key.usages does not permit this operation"
    *  name: "InvalidAccessError"
    * }
    */
    console.log("Wrapped Key", wrapKeyResult);
  } catch (error) {
    console.error("something went wrong", error);
    throw error; 
}

foo()
  .then((res) => {
    console.log("I succeeded!");
  })
  .catch((error) => console.log("I failed with ", error));

【问题讨论】:

    标签: javascript typescript web cryptography


    【解决方案1】:

    generateKey() 中应用了错误的key usages。正确的是 wrapKeyunwrapKey,因为 RSA 密钥对用于包装/解包对称 AES-GCM 密钥:

    async function foo() {
        try {
            const cryptoKeyPair = await window.crypto.subtle.generateKey(
                {
                    name: "RSA-OAEP",
                    modulusLength: 4096,
                    publicExponent: new Uint8Array([1, 0, 1]),
                    hash: "SHA-256"
                },
                true,
                ["wrapKey", "unwrapKey"]                      // Apply wrapKey and unwrapKey here! 
            );
            const publicKey = cryptoKeyPair.publicKey;
    
            const fileKey = await window.crypto.subtle.generateKey(
                { name: "AES-GCM", length: 256 },
                true,
                ["encrypt", "decrypt"]
            );
    
            const wrapKeyResult = await window.crypto.subtle.wrapKey(
                "raw",
                fileKey,
                publicKey,
                publicKey.algorithm.name
            );
            console.log("Wrapped Key", new Uint8Array(wrapKeyResult));
      
        } catch (error) {
            console.error("something went wrong", error);
            throw error;
        }
    }
    
    foo()
        .then((res) => {
            console.log("I succeeded!");
        })
        .catch((error) => console.log("I failed with ", error));

    【讨论】:

      猜你喜欢
      • 2023-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-23
      • 2020-03-15
      • 2021-10-03
      • 2011-11-07
      相关资源
      最近更新 更多