首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Webcrypto PBKDF2-SHA1

Webcrypto PBKDF2-SHA1
EN

Stack Overflow用户
提问于 2020-05-09 02:58:39
回答 1查看 691关注 0票数 2

我在使用PBKDF2和Webcrypto时遇到了问题。我想在SHA-1算法中使用PBKDF2 .目前,我有

代码语言:javascript
复制
const ENCODING = "utf-8";
const HMACSHA1 = {name: "HMAC", "hash" : "SHA-1"};
const PBKDF2SHA1 = {name: "PBKDF2", "hash": "SHA-1"};

// str2binb takes a string and outputs an ArrayBuffer

async function pbkdf2_generate_key_from_string(string) { //  Working
  return crypto.subtle.importKey(
    "raw",
    str2binb(string),
    PBKDF2SHA1,
    false,
    ["deriveKey", "deriveBits"],
  );
}

async function pbkdf2_derive_salted_key(key, salt, iterations) {  // Not working
  return crypto.subtle.deriveKey(
    {
      "name": "PBKDF2",
      "salt": salt,
      "iterations": iterations,
      "hash": "SHA-1",
      "length": 160
    },
    key,
    {
      "name": "HMAC"
      "hash": "SHA-1",
      "length": 160
    },
    true,
    [ "encrypt", "decrypt"]
  );
}

不过,我知道我一定使用错了,因为它是一个受支持的密钥派生算法,并且根据Mozilla的奇妙的文档,在derivedKeyAlgorithm下,HMAC和HMAC-SHA1 1一样受支持。我还让它非常直接地与AES-GCM一起工作。

当我尝试时,我得到的错误信息,

代码语言:javascript
复制
salt = b64binb("QSXCR+Q6sek8bf92"); // ArrayBuffer
key = await pbkdf2_generate_key_from_string("pencil");
x = await pbkdf2_derive_salted_key(key, salt, 4096)

Uncaught DOMException: Cannot create a key using the specified key usages.

注意:据我所知,不再推荐SHA1,这是用于遗留支持的。

注2:当我将上面的内容替换为,

代码语言:javascript
复制
async function pbkdf2_derive_salted_key(key, data, salt, iterations) {  // Not working
  return crypto.subtle.deriveKey(
    {
      "name": "PBKDF2",
      salt: salt,
      "iterations": iterations,
      "hash": "SHA-1",
    },
    key,
    {
      "name": "AES-GCM",
      "length": 256
    },
    true,
    [ "encrypt", "decrypt"]
  );
}

谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-05-09 11:45:26

deriveKey中,参数keyUsages必须更改为["sign", "verify"]。然后代码工作(因为b64binbstr2binb没有发布,下面的代码使用适当的替代品):

代码语言:javascript
复制
const b64binb = base64String => Uint8Array.from(atob(base64String), c => c.charCodeAt(0));
const str2binb = str => new TextEncoder().encode(str);
const buf2hex = buffer => Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('');

async function pbkdf2_generate_key_from_string(string) { 
    return crypto.subtle.importKey(
        "raw",
        str2binb(string),
        {
            name: "PBKDF2",
        },
        false,
        ["deriveKey", "deriveBits"], 
    );
}

async function pbkdf2_derive_salted_key(key, salt, iterations) {  
    return crypto.subtle.deriveKey(
        {
            name: "PBKDF2",
            salt: salt,
            iterations: iterations,
            hash: {name: "SHA-1"}
        },
        key,
        {
            name: "HMAC",
            hash: "SHA-1",
            length: 160
        },
        true,
        ["sign", "verify"] // <--------------------- Fix!
    );
}

async function test(){
    salt = b64binb("QSXCR+Q6sek8bf92"); // ArrayBuffer
    key = await pbkdf2_generate_key_from_string("pencil");
    x = await pbkdf2_derive_salted_key(key, salt, 4096)

    console.log(buf2hex(await window.crypto.subtle.exportKey("raw", x)));
}

test();

使用此密钥,window.crypto.subtle.sign使用HMAC-SHA1 1创建签名。

更新:

由于在https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto中通常指定密钥的使用,因此必须将["encrypt", "decrypt"]作为AES-GCM的keyUsages参数和HMAC-SHA的["sign", "verify"]参数。

为什么["encrypt", "decrypt"]为AES-GCM?AES-GCM用于加密/解密消息:AES描述分组密码 (允许对单个块进行加密)和GCM 操作方式 (允许对多个块进行加密)。GCM提供机密性、真实性和完整性。

为什么["sign", "verify"]为HMAC?HMAC用于签名/验证消息:某些操作模式(如CBC )只提供机密性。另外,为了提供真实性和完整性,可以使用MAC (例如,基于密码散列函数的特定类型的HMAC,例如SHA家族中的一个)对消息进行签名。MAC通常是根据密文而不是明文(https://crypto.stackexchange.com/q/202)计算的。关于SHA1漏洞,请参见HMAC-SHA1 1和HMAC-SHA1 256 这里这里的比较。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61691214

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档