首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Crypto中重现SubtleCrypto时出现问题

在Crypto中重现SubtleCrypto时出现问题
EN

Stack Overflow用户
提问于 2021-07-07 16:46:43
回答 1查看 522关注 0票数 0

我有一些利用SubtleCrypto的代码,可以加密密钥并将其存储在数据库中。

对于另一个功能,我必须能够在节点12中加密它。没有SubtleCrypto,我必须在Crypto中重新创建该功能。

我得到了相同大小的输出,但它似乎不能被SubtleCrypto解密,我正在试图找出我错在哪里。

以下是在浏览器上使用SubtleCrypto运行的代码:

代码语言:javascript
复制
key = getKeyMaterial(password)];
salt = base64ToArraybuffer(optionalSalt)
aesKey = crypto.subtle.deriveKey(
{
    name: constants.algorithms.pbkdf2,
    salt: salt,
    iterations: pbkdf2Iterations,
    hash: { name: constants.hash.sha256 },
},
key,
{
    name: constants.algorithms.aesGcm,
    length: aesWrapKeyBitsLength,
},
true,
['wrapKey', 'unwrapKey']
),
return {
  salt: arraybufferTobase64(salt),
  aesKey: aesKey,
}


function getKeyMaterial(password) {
var enc = new TextEncoder();
crypto.subtle.importKey(
  constants.format.raw,
  enc.encode(password),
  {
    name: constants.algorithms.pbkdf2,
  },
  false,
  ['deriveKey']
)

没有SubtleCrypto,在节点12中,我被迫使用加密库。这是我的,代码的当前迭代。

代码语言:javascript
复制
const ivByteLength = 12;

function wrapKey(privateKey, aesKey) {
  const IV = crypto.randomBytes(ivByteLength);
  const ALGORITHM = 'aes-256-gcm';

  const cipher = crypto.createCipheriv(ALGORITHM, aesKey, IV);
  let encrypted = cipher.update(privateKey, undefined, 'binary');
  encrypted += cipher.final('binary');

  const authTag = cipher.getAuthTag();

  encrypted += authTag;
  const output = {
    wrappedKey: arraybufferTobase64(Buffer.from(encrypted, 'ascii')),
    iv: arraybufferTobase64(IV),
  };
  return output;
}

async function deriveAesGcmKey(password, salt) {
  return new Promise((resolve, reject) => {
    crypto.pbkdf2(password, salt, 100000, 32, 'sha256', (err, derivedKey) => {
      if (err) reject(err);
      else resolve(derivedKey);
    });
  });
}

function arraybufferTobase64(buffer) {
  let binary = '';
  const bytes = new Uint8Array(buffer);
  const len = bytes.byteLength;
  for (let i = 0; i < len; i += 1) {
    binary += String.fromCharCode(bytes[i]);
  }
  return btoa(binary);
}

function base64ToArraybuffer(base64) {
  const binary = atob(base64);
  const len = binary.length;
  const bytes = new Uint8Array(len);
  for (let i = 0; i < len; i += 1) {
    bytes[i] = binary.charCodeAt(i);
  }
  return bytes;
}

封装后的密钥在两种实现中都有相同的大小,但Node生成的密钥无法在浏览器中解封。

我是不是假设了一些默认值是错误的呢?

EN

回答 1

Stack Overflow用户

发布于 2021-07-07 16:54:32

NodeJS在crypto包中有一个叫做webcrypto类的东西,它有微妙的加密实现。

来自Docs的示例

代码语言:javascript
复制
const { subtle } = require('crypto').webcrypto;

async function digest(data, algorithm = 'SHA-512') {
  const ec = new TextEncoder();
  const digest = await subtle.digest(algorithm, ec.encode(data));
  return digest;
}

另请查看:https://nodejs.org/api/webcrypto.html#webcrypto_class_subtlecrypto

编辑:

正如Node较低版本的注释中所说,您可以使用polyfill,如https://www.npmjs.com/package/@peculiar/webcrypto,它是比Node10更高的Nodejs版本的webcrypto实现

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

https://stackoverflow.com/questions/68282852

复制
相关文章

相似问题

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