簡體   English   中英

我如何重新加密使用 nodejs 加密生成的 aes 加密私鑰

[英]how do i reencrypt a aes encrypted private key generated using nodejs crypto

我試圖解密一個私有的 AES 加密 RSA 密鑰,並用相同的 AES 算法重新加密它,但使用不同的密碼。 我使用這種方法創建了一個 RSA 密鑰對:

crypto.generateKeyPairSync('rsa', {
        modulusLength: 2048,
        publicKeyEncoding: {
          type: 'pkcs1',
          format: 'pem',
        },
        privateKeyEncoding: {
            type: 'pkcs1',
            format: 'pem',
            cipher: 'aes-256-cbc',
            passphrase: secret
        }
      });

這是通過此方法生成的示例私鑰:

-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-256-CBC,B25B895829F89685570676A6C53B4E9F

xb/IOI6S1rXqxo+N1Aba1M4xCqDG8u5OGBiF/zvDnKzZ/rV7/TTVIhQouZKdq+26
XMQDWGlRx1YQqWajJUZzbvixdWR3pacRpR1Mli1WPIU3rtWwOlYVgL3TqtN19IK+
NEMMrGpbnUQmXM1M5ZExRrKYw9qPI3VJwmCuE0j19+FoYZJT/5v861RcNs18v8hz
[...]
-----END RSA PRIVATE KEY-----

我想解密使用aes-256-cbc和密碼加密的私鑰,然后使用另一個密碼和相同的 AES 算法重新加密。

我已經嘗試過以下方法,但未能成功:

const decryptRsaPrivateKey = (privateKey, oldPassword, newPassword) => {
    const keyLines = privateKey.split('\n');

    // Extract the DEK-Info line
    var dekInfoLine = keyLines[2]

    // Extract the encryption algorithm and IV from the DEK-Info line
    const [, algorithm, ivHex] = dekInfoLine.match(/DEK-Info: (.+),(.+)/);
    const iv = Buffer.from(ivHex, 'hex');

    // Remove the DEK-Info line and the header/footer lines
    keyLines.splice(2, 1);
    keyLines.splice(0, 1);
    keyLines.splice(-1, 1);

    // Join the remaining lines and base64-decode the key
    const encodedKey = keyLines.join('');
    const decipher = crypto.createDecipheriv(algorithm, Buffer.from(oldPassword), iv);
    let decryptedKey = decipher.update(encodedKey, 'base64', 'binary');
    decryptedKey += decipher.final('binary');

    // Encrypt the key with the new password
    const cipher = crypto.createCipheriv(algorithm, Buffer.from(newPassword), iv);
    let encryptedKey = cipher.update(decryptedKey, 'binary', 'base64');
    encryptedKey += cipher.final('base64');

    // Add the DEK-Info line and the header/footer lines
    const dekInfo = `DEK-Info: ${algorithm},${iv.toString('hex')}`;
    return `-----BEGIN RSA PRIVATE KEY-----\n${dekInfo}\n\n${encryptedKey}\n-----END RSA PRIVATE KEY-----`;
}

這是我從這個方法得到的錯誤:

node:internal/crypto/cipher:116
    this[kHandle].initiv(cipher, credential, iv, authTagLength);
                  ^

RangeError: Invalid key length
    at Decipheriv.createCipherBase (node:internal/crypto/cipher:116:19)
    at Decipheriv.createCipherWithIV (node:internal/crypto/cipher:135:3)
    at new Decipheriv (node:internal/crypto/cipher:289:3)
    at Object.createDecipheriv (node:crypto:149:10)
    at Module._compile (node:internal/modules/cjs/loader:1159:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1213:10)
    at Module.load (node:internal/modules/cjs/loader:1037:32)
    at Module._load (node:internal/modules/cjs/loader:878:12) {
  code: 'ERR_CRYPTO_INVALID_KEYLEN'
}

我還閱讀了節點的文檔,但沒有發現任何可以幫助我的東西。

先感謝您。

密鑰通常使用crypto.createPrivateKey()導入。 對於必須指定密碼的加密密鑰也是如此。
可以使用keyObject.export()進行導出。 如果要對密鑰進行加密,則必須指定密碼和算法。

如果要更改現有加密密鑰的密碼,過程類似:使用舊密碼導入,使用新密碼導出。

例子:

var crypto = require('crypto');

// Generate keypair
var secret ='secret';
var keyPair = crypto.generateKeyPairSync(
    'rsa', 
    {
        modulusLength: 2048,
        publicKeyEncoding: {type: 'pkcs1', format: 'pem'},
        privateKeyEncoding: {type: 'pkcs1', format: 'pem', cipher: 'aes-256-cbc', passphrase: secret}
    }
);

var encPkcs1Pem = keyPair.privateKey;
console.log(encPkcs1Pem);

// Import
var privateKey = crypto.createPrivateKey({key: encPkcs1Pem, type: 'pkcs1', format: 'pem', passphrase: secret});
//var privateKey = crypto.createPrivateKey({key: encPkcs1Pem, passphrase: secret}); // works also

// Export with new passphrase
var secret_2 ='another secret';
var encPkcs1Pem_2 = privateKey.export({type: 'pkcs1', format: 'pem', cipher: 'aes-256-cbc', passphrase: secret_2});
console.log(encPkcs1Pem_2);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM