【问题标题】:Nodejs `crypto.publicEncrypt` would not take public key generated by `ssh-keygen rsa`Nodejs `crypto.publicEncrypt` 不会采用 `ssh-keygen rsa` 生成的公钥
【发布时间】:2021-03-22 01:10:24
【问题描述】:

我使用ssh-keygen rsa 生成了一个 RSA 密钥对。生成的公钥如下所示:

ssh-rsa AAAAB3NzaC1yc2EAAA...

当我尝试在 Node.js 中使用 crypto 来加密纯字符串时,

const fs = require('fs');
const { publicEncrypt } = require('crypto');

const publicKey = fs.readFileSync('$path/to/publicKey').toString();

const encryptedToken = publicEncrypt(publicKey, Buffer.from('some plain string'));

它会给出以下错误:

Error: error:0909006C:PEM routines:get_name:no start line
  at node:internal/crypto/cipher:78:12
  ...
 library: 'PEM routines',
 function: 'get_name',
 reason: 'no start line',
 code: 'ERR_OSSL_PEM_NO_START_LINE'

我对密码学很陌生,只知道公钥/私钥加密的一般概念,因此非常感谢任何建议。

编辑:

我知道crypto 带有生成密钥对的方法,所以我想问题更多是关于为什么ssh-rsa 公钥在这里不起作用。

【问题讨论】:

    标签: node.js rsa cryptojs


    【解决方案1】:

    发布的公钥是OpenSSH格式,NodeJS的crypto模块不支持,见crypto.publicEncrypt(key, buffer)的文档。

    但是,OpenSSH 格式的密钥可以转换为 NodeJS 可以处理的格式。这可以通过工具来完成,例如ssh-keygen,或通过库,例如node-sshpk.

    或者,可以使用OpenSSL 直接以所需格式生成密钥。

    以下示例使用 node-sshpk 库并将 OpenSSH 私钥转换为 PEM 编码的 PKCS8 密钥,并将 OpenSSH 公钥转换为 PEM 编码的 X.509/SPKI 密钥。 NodeJS 支持这两种目标格式:

    var sshpk = require('sshpk');
    var crypto = require('crypto');
    
    var privateKeyOpenSSH = `-----BEGIN OPENSSH PRIVATE KEY-----
    b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABFwAAAAdzc2gtcn
    NhAAAAAwEAAQAAAQEApcFmUiObzYdRrKivbYrUwJ8plRfjcgA1nXIHpMKj4q0l4vatprYe
    vNS2l06y2Qvz1Txu7AeS9+zT673zczwvLgENcZb6lXA576XMLjcmZhnNKXDRnRV/UCMlea
    jdwdhQ93YJpsGRCUewD8k6IOO6G/MVAQ433ybBuCPJysTLWNk2Vv/J3VrLkBWGLiwOUcnZ
    pR17/mm6QBOsLRAuBs1jELcid1Jdpc8wfULlrSdCfw/P2mXOqpuTMhSEBy4yE+W6V54MSI
    Vw4BaxlrcAmC/Rh7OHJrhuIEmmOStqmMPe7HvFKNTjqzISAiyWmPWWwI9UuP4g7b0p7GAk
    0YMevLPQnwAAA9jLWAaqy1gGqgAAAAdzc2gtcnNhAAABAQClwWZSI5vNh1GsqK9titTAny
    mVF+NyADWdcgekwqPirSXi9q2mth681LaXTrLZC/PVPG7sB5L37NPrvfNzPC8uAQ1xlvqV
    cDnvpcwuNyZmGc0pcNGdFX9QIyV5qN3B2FD3dgmmwZEJR7APyTog47ob8xUBDjffJsG4I8
    nKxMtY2TZW/8ndWsuQFYYuLA5RydmlHXv+abpAE6wtEC4GzWMQtyJ3Ul2lzzB9QuWtJ0J/
    D8/aZc6qm5MyFIQHLjIT5bpXngxIhXDgFrGWtwCYL9GHs4cmuG4gSaY5K2qYw97se8Uo1O
    OrMhICLJaY9ZbAj1S4/iDtvSnsYCTRgx68s9CfAAAAAwEAAQAAAQAstgRxt6U5RX0kg8P+
    WmqVItnGm9EAWUodFDs3mEE4zdfgZwXkaE/WQ9KU8eeQYIb/R/PruwdL1Rg9CNn4hY18bV
    BBCabCVKlsGV8AQGQdOmx69zGzm67h4Pkk3gYjWcRNXAuybZg/1pSJTZBees8i5ukNhdZQ
    XVX347908KyhZFb4jlYws7gbOkVBP7ludHSnnrodL91F2ouKrgplLfWu40sgU3fSpSybby
    3Llt+FUW6UjCErp54c2LS5vZtvTJK+wVr2fYF4Y1Sgmv+JZ4bJUkZgaxzcHoOLF5GfuQFo
    dvJVxbSXPUhk7JW7ur9hHLkEaJtYf0xf1TwJdPRQxu3xAAAAgQCui5wvYjZrCM9wWDXpWh
    1dNGPIJQuX8aCxi2tfTkRYlkPUWFSYd+orQr53/FPTxLdwe9lAe8x0Xkr+wMga6771ywHw
    sT6xk7nCabXcN6PQCn5DjYMtLPfa5rY3+yHR01pVSzo9l6JcvangU1xyw7MRYj0LGZVSbp
    U/beRO/bXekQAAAIEA0uUTVG9wPiqZRTLT6H8rQ4ZK96VcTF+CnmJUO+3Fsp/D7jfYItZF
    2GcqzWYv6tsvumdhZt0dziXBy7fAJDW88k/nq+BNTlDXEYzkEA+x13eaLAzfI08SwlAnF5
    zxZUo8yIsjKtyt9gs1+VVgtwpvvqUVDUibjbWxaE4OWtdLjwUAAACBAMk02gcYkJylXw12
    4me1vtWpw7/7pga3eK0Y4ZTZgpCZXhrLnl9yWXrVIlvV8dLJQI88s7+1CRU9HPi+2BGtgI
    mJ5crYws7q0QgLODg1rDosd4vkkKok5XPUsrKDLxwme+Ipq26IdRyoJF2ZiRHvPG5ajjmK
    gWByjcdktmXM+UpTAAAAHHRmbG9yZXNfZHQwMUB0ZmxvcmVzX2R0MDEtUEMBAgMEBQY=
    -----END OPENSSH PRIVATE KEY-----`
    
    var publicKeyOpenSSH = `ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQClwWZSI5vNh1GsqK9titTAnymVF+NyADWdcgekwqPirSXi9q2mth681LaXTrLZC/PVPG7sB5L37NPrvfNzPC8uAQ1xlvqVcDnvpcwuNyZmGc0pcNGdFX9QIyV5qN3B2FD3dgmmwZEJR7APyTog47ob8xUBDjffJsG4I8nKxMtY2TZW/8ndWsuQFYYuLA5RydmlHXv+abpAE6wtEC4GzWMQtyJ3Ul2lzzB9QuWtJ0J/D8/aZc6qm5MyFIQHLjIT5bpXngxIhXDgFrGWtwCYL9GHs4cmuG4gSaY5K2qYw97se8Uo1OOrMhICLJaY9ZbAj1S4/iDtvSnsYCTRgx68s9Cf whatever`;
    
    // Convert
    var privateKey = sshpk.parsePrivateKey(privateKeyOpenSSH, 'ssh');
    var publicKey = sshpk.parseKey(publicKeyOpenSSH, 'ssh');
    var privateKeyPkcs8 = privateKey.toBuffer('pkcs8');
    var publicKeyX509 = publicKey.toBuffer('pkcs8');
    console.log(privateKey.toString('ssh'));
    console.log(publicKey.toString('ssh'));
    console.log(privateKeyPkcs8.toString('utf8')); // -----BEGIN PRIVATE KEY-----...
    console.log(publicKeyX509.toString('utf8')); // -----BEGIN PUBLIC KEY-----...
    
    // Encrypt/Decrypt
    var plaintext = Buffer.from('The quick brown fox jumps over the lazy dog', 'utf8');
    var ciphertext = crypto.publicEncrypt(publicKeyX509.toString('utf8'), plaintext);
    var decryptedText = crypto.privateDecrypt(privateKeyPkcs8.toString('utf8'), ciphertext);
    
    console.log('Ciphertext, base64 encoded: ', ciphertext.toString('base64'));
    console.log('Decrypted text: ', decryptedText.toString('utf8'));    
    

    【讨论】:

      猜你喜欢
      • 2016-09-15
      • 2020-08-06
      • 2013-09-02
      • 2021-09-10
      • 2019-05-05
      • 2014-10-22
      • 1970-01-01
      相关资源
      最近更新 更多