简体   繁体   中英

Nodejs `crypto.publicEncrypt` would not take public key generated by `ssh-keygen rsa`

I used ssh-keygen rsa to generate an RSA keypair. The generated public key looks like this:

ssh-rsa AAAAB3NzaC1yc2EAAA...

When I try to use crypto in Node.js to encrypt a plain string,

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'));

it would give out the following error:

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'

I am pretty new to cryptography and know only the general idea of public/private key encryption so would really appreciate any advice.

Edit:

I understand that crypto comes with method to generate key pairs, so I guess the question is more about why the ssh-rsa public key did not work here.

The posted public key is in OpenSSH format, which is not supported by NodeJS's crypto module, see documentation of crypto.publicEncrypt(key, buffer) .

However, keys in OpenSSH format can be converted to formats that can be processed by NodeJS. This can be done via tools, eg ssh-keygen , or via libraries, eg node-sshpk .

Alternatively, keys can be generated directly in the required format using OpenSSL .

The following example uses the node-sshpk library and converts an OpenSSH private key to a PEM encoded PKCS8 key and an OpenSSH public key to a PEM encoded X.509/SPKI key. Both target formats are supported by 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'));    

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM