Node Openpgp encrypt can not find valide key - node.js

When I try use Openpgp#5.5.0 to encrypt my string
get error Could not find valid encryption key packet in key 637691f642a09df8
, how can i fix this issue ?
my public key
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQINBGNJlV4BEACw+tHTiJJ9METBa6+ZjF3SEPsidcsPv6osFQJREoVUmwhKBdwN
6YLr05Gkd+FYzUYU6STKtH9bBBoXjTY1qBMHZVFZvKWV8IJ680+xzz5JvgVyhu4c
EvWowpOSJTDl0sP06n2kItGqPFo+kHSinoA/OmZha7p0ljOMiMqbL0ysQ3LbrZmb
NLQysFTsKzgynKa40z5SjamWx8iLsa28mXZbLMsdY67f0Du9wAmwa036RIm5CNSO
vw6mzN1BzQVYR5IxwajxodTWXjmRG9jk4/F+FxCin5YObVRQuj28ggWboPRhcGJi
vap4ew+DbdwWSYzLNJIHocpRHNCtVOgPl/I35N6CHuxf7/c+428iNBxdN3ICyadC
y853OnusB9DDVjhVgpnbJ4b+L5pYYToQrISUQo0r3YCJyPSMfMo96tmh58Gv70oC
oMxFgafjuSyD7GvCupGCh3yuAtqLYuMVmS3OQZWAqcwsJQYNxURTfppn0Jl4MVRU
M/2vmjR7dqX+vdGtwK3Xu844w2QTzGPzPqHrXRNDm2evkHc7YI3hsOw2mRgPSzqn
aiyXXS4Q1IMSeIIXUOL19S5dfNMKeNO2tAfobqwkXbN4TwGfHlj72Bx8UPJHvThI
5Fzv+jtRb/kcr+QTRHUmzOuhftOb76RXhfjqTiad2/b2n2mJWZsv4YchgQARAQAB
tDVLYW8gRHJhZ29uIChVUFMgU21hcnRWaWV3IGRhdGEga2V5KSA8a2RyYWdvbkB1
cHMuY29tPokCTgQTAQgAOBYhBFFqZd3nc1CngvkZm2N2kfZCoJ34BQJjSZVeAhsD
BQsJCAcCBhUKCQgLAgQWAgMBAh4BAheAAAoJEGN2kfZCoJ344H8P/Aij5JhKGOAG
rmRoHkRpuVdJYGXpJxUAjjah6Z5j6qRC+/FIdrAYxGoLDgshDEqJPMRddAT/xepF
QDtD/noqFyd8JJUSkzH/zrUcohs3oG9Rd5WybYu85AHQutBHGG5H/ghuJ3s1zXfR
fFe34j3SzhCcXg67Tqipl2t+ap8lQkWEpJ//CHknsHt91B5khx9Xv4QQOLzuCz56
rLDf5GqghAwHpA3BfuUnAmuw8wFTymdlR4KSIh5ttwG/GT5A6L8MGydI4y4dUSHt
umsn1JwvHMaXvwGy4ReJK6Z8o4H022Qmmz8pnVjGNz1CLzupcKGEPbN9mO4/wv/k
tzU4qPbKxoCu5UewMvqpeXLvlpn2DlTR8NivQ3847xokhfR+UlEnIEbcwcWdvJc2
mL8xKhvFh0sBQK3OyyXJzL0pw9eLAdj5i5sUO+hl6Dy2eo8QxfNw7zaw8L72fk3n
HIJFTB6RpCHXUw6Jb4K5NODVuKJ4z9r5okqzHA7gaALEcT/q9CQ3p044vLbrPxMD
s/+RX6pJn1c3azpMLhSQFH/C3gZySoPujLqcNDvjkluI1ErPD9dR7OX0Od345kkp
DZykeb1DbaO+OR3At1fEBJ1S8d3xngrpuVjSSsXOWWNd14nw9T0ZIcxkISDHyllz
M7QEGBSUvOR14CWnx9uAHVLNyruaKBix
=n4J7
-----END PGP PUBLIC KEY BLOCK-----
const publicKeyArmored = ``;
console.log('Get Keys')
const publicKey = await openpgp.readKey({armoredKey: publicKeyArmored})
const encrypted = await openpgp.encrypt({
message: await openpgp.createMessage({ text: 'Hello, World!' }),
encryptionKeys: publicKey
});
})();```

Related

nodejs openpgp hashing algorithm to SHA256

I managed to sign message with OpenPGP sign() function,but how can I change the hashing algorithm to SHA256?
async function pgpSignMessage(privateKey,messageToSign,callback) {
const unsignedMessage = await openpgp.createCleartextMessage({ text: messageToSign });
const cleartextMessage = await openpgp.sign({
message: unsignedMessage,
signingKeys: privateKey,
});
console.log("pgpSignMessage cleartextMessage ",cleartextMessage );
return callback(cleartextMessage );
);
ouput :
pgpSignMessage cleartextMessage
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
This is a testing message
-----BEGIN PGP SIGNATURE-----
wsBzBAEBCgAGBQJjTOMPACEJEPjzUwweaxTJFiEEcJyNNiL/3PuC/Rze+PNT
DB5rFMnA2wf+OQV8+S1o12hrHgIOy362xHk7jk+bhUf2DzosyMIb5/FaP58a
Y2VxZUOMkYPFJeiJ9dO7z+25QjbUgbZz5ikExdPIIwmfY1BPX8jgWEQAniOD
ZZVg+pG2hALuZwzBchw+onvoPyyZLSNajkY4rA/wXexuAljWqWTpypoN51iQ
O/E4TN2FbAIQOq89tzS5MXhEAZe4bYHH4cUwsQiaIjA+2OjrspPJt+3/nosP
1f6k6wgZKuPDbyK6KKSqtb0tzFmIVkF+4+VF+vQFi7kx5utWn/nXOWO78tUV
s6dn23+GdJ5sLaFUT5vPDKux3dddErPOKEam/hJUe5VoO2LzeNO5Ww==
=KsDz
-----END PGP SIGNATURE-----
Having access to the openpgp.js sources (in this case it is latest master commit), and going down through the sign() function code, you'll occasionally get to this:
export async function getPreferredHashAlgo(key, keyPacket, date = new Date(), userID = {}, config) {
let hashAlgo = config.preferredHashAlgorithm;
let prefAlgo = hashAlgo;
if (key) {
const primaryUser = await key.getPrimaryUser(date, userID, config);
if (primaryUser.selfCertification.preferredHashAlgorithms) {
[prefAlgo] = primaryUser.selfCertification.preferredHashAlgorithms;
hashAlgo = crypto.hash.getHashByteLength(hashAlgo) <= crypto.hash.getHashByteLength(prefAlgo) ?
prefAlgo : hashAlgo;
}
}
...
So, it would first pick value from the config.preferredHashAlgorithm. Then, if primary user's id certification contains preferred hash algorithms subpacket, and first value's hash length is longer then config's one, it will pick it up.
You may get more information about your key via gpg --list-packets command.

NOdeJs Rest API response encoded with private key

I have been supplied with a public and private key to call a restAPI in nodejs.
Both keys are in clear ASCII format.
I use the following code to encript my message:
(async () => {
// put keys in backtick (``) to avoid errors caused by spaces or tabs
// ENCRYPT
const publicKeyArmored = fs.readFileSync(publicKeyFile, {
encoding: 'utf8',
flag: 'r'
});
const publicKey = await openpgp.readKey({ armoredKey: publicKeyArmored });
const encrypted = await openpgp.encrypt({
message: await openpgp.createMessage({ text: 'Hello, World!' })
, encryptionKeys: publicKey
// , signingKeys: privateKey // optional
});
console.log("Encrypted:", encrypted); // '-----BEGIN PGP MESSAGE ... END PGP MESSAGE-----'
}
However when I try to decrypt the response, all the code examples I have found seem to require a passphrase to use the private key supplied, but this is not encoded in any way, it's again plain ascii, begining with :
-----BEGIN PGP PRIVATE KEY BLOCK-----
Version: GnuPG v2.0.22 (GNU/Linux)
lQO+BGHApmABCAC70QG0T3bh1MVRGKmY9cOM2NFEie2KXCLGXUPa+2B5JOnDypGX
msoLau8FtKIqvAVAYSsONlE4P4RcltyrOTHLMvWhu73ZTJIBu6GGkgM6bKOtu2Rp
/VbPylPIXrkA3A4s0089VGgmFqJul04lit2svLwxD31ZEIY3Ke3kd0dV0nM4npRO
EZUPR5Qr6KCwBsL+ZHbDuG2YrC7oKcnJTXcdszrF7+FLAwI8viZhJOXyagJRioXd
/H/IpauXyvejN22/eRjch9IRMSz+qh0avj9tcuuJ1k4sBQQukeoIoPwFe9Rb9TY2 .....
the following code suggests I need a passphrase, but this key does not appear to require one:
async function decrypt() {
const privateKey = (await openpgp.key.readArmored([privateKeyArmored])).keys[0];
await privateKey.decrypt(passphrase);
const encryptedData = fs.readFileSync("encrypted-secrets.txt");
const decrypted = await openpgp.decrypt({
message: await openpgp.message.readArmored(encryptedData),
privateKeys: [privateKey],
});
console.log(decrypted.data);
}
SO how do I use it without a passphrase?
Thank you in advance for your xmas spirit and any help!
Your private key is ASCII armored, so it is possible to transfer it in text representation. After calling gpg --dearmor on it you'll get the binary data. Also private key may be stored using the password encryption, or not encrypted at all (in the second case you will not need to call privateKey.decrypt()). To check this you may use the command gpg --list-packets keyfile.asc.

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, e.g. ssh-keygen, or via libraries, e.g. 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'));
const {NodeSSH} = require('node-ssh')
ssh = new NodeSSH()
var sshpk = require('sshpk');
var crypto = require('crypto');
var privateKeyOpenSSH = `private key ecdsa `
var publicKeyOpenSSH = `public key ecdsa`;
// Convert
var privateKey = sshpk.parsePrivateKey(privateKeyOpenSSH, 'ssh');
var publicKey = sshpk.parseKey(publicKeyOpenSSH, 'ssh');
var privateKeyPkcs8 = privateKey.toBuffer('pkcs8');
var publicKeyX509 = publicKey.toBuffer('pkcs8');
ssh.connect({
host: process.env.SSH_host,
username: process.env.SSH_user,
privateKey: Buffer.from('C:/Users/aniru/.ssh/id_ecdsa'),
passphrase:'passphrase string'
})
.then(() => {
console.log("ssh connected");
ssh.execCommand("redis-cli ping", { cwd: "/var/www" }).then((result) =>
{
console.log("STDOUT: " + result.stdout);
console.log("STDERR: " + result.stderr);
});
});

Node openpgp error when encrypting: Could not find valid key packet for encryption in key

I have a error when trying to encrypt a string with a pgp public key:
'Could not find valid key packet for encryption in key 9ae788ff8eec0b31'
This error doesn't appear with every key but with most of them. Here one of the keys that errors:
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: BCPG v1.43
mI0EXQJU0gEEAKZKsTmlR71mPgzQR6hyGJXR4tuoH/RgJPnZGCKPlJqCj8GCvlTa
Jqy5gUZQJItwS4ssFU56+fI1a47oe08covHWgLAsGRWCxsD/oneFhddPhhZkHOui
s1CW3CNDQ8hhl/DykhUoegKCmvNDzRVsD4y7ueLkzAisu3MH3ShQWDB/ABEBAAG0
CUxJTlhPIFNBU4icBBABAgAGBQJdAlTSAAoJEPa8OTh7Vcnz4kID/0KL7RBA5Z83
WuirfaVXF+Kqi4QXQO4EBUUknSbO+igRSJ/MLV4NROuhn2AZ3YWXK9B8rLsaZy9Q
49/rr1lPn648Wq2lAoN7uLwtycspFQscjLT76hDMnoOvJGzjrpi+xC7n0W7ggLRN
TkCUB8b+OBvwPhptny8kS6DASwew0Fp7
=2Sis
-----END PGP PUBLIC KEY BLOCK-----
Here is the function im using to encrypt
const openpgp = require('openpgp')
async function pgpEncrypt(pubkey, message) {
await openpgp.initWorker({ path: 'openpgp.worker.js' })
const options = {
message: await openpgp.message.fromText(message), // input as Message object
publicKeys: (await openpgp.key.readArmored(pubkey)).keys, // for encryption
armor: false
}
const cipherText = await openpgp.encrypt(options)
return cipherText.data
}
What's wrong with this? how can i ensure the key works with this library?
It is a version issue. Try the 4.10.8 version of openpgp. Use the following lines for the dependencies.
"dependencies": {
"openpgp": "^4.10.8"
}

Get public key from certificate in nodejs

I need to get a server's public key from its SSL cert. I'm getting the cert as follows:
https.request(options, res => {
const cert = res.connection.getPeerCertificate();
const publicKey = cert.????()
}
I can't find a way to get the public key from the certificate though. Are there any libraries that can do this?
I'm looking to use the public key to encrypt some data:
const encryptedBuffer = crypto.publicEncrypt({
key: publicKey,
padding: crypto.constants.RSA_PKCS1_PADDING
}, utf8Payload)
I see that the certificate has a "raw" buffer, but using that as the publicKey fails.
-----BEGIN CERTIFICATE-----
MIID3DCCAsSgAwIBAgIUOaZ5jqRgBz4HjwilIbDz5+Polh0wDQYJKoZIhvcNAQEL
BQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsT
.....
C1c3RqArBaz/c4SqHhyKaHRFinDs5kjnAz+H4+QvQAH0UXgHG050YEZjeZPXMRJB
4I0fzGC++82WXhcwSPaX+BJZuv2bEIfxbyxdVanGmIJdYsGFwSc9sIf2j1cK22A5
vdboEXXkQnqF552iNy9HGRubNQ1VkqITELToRcqcvAo=
-----END CERTIFICATE-----
If the format of the certificate is as above, it can be done with crypto module. No dependency on other packages.
crypto.createPublicKey(cert).export({type:'spki', format:'pem'})
output format:
-----BEGIN PUBLIC KEY-----
..........................
-----END PUBLIC KEY-----
or
crypto.createPublicKey(cert).export({type:'pkcs1', format:'pem'})
output format:
-----BEGIN RSA PUBLIC KEY-----
..............................
-----END RSA PUBLIC KEY-----
see more on the document
I see that the certificate has a "raw" buffer, but using that as the
publicKey fails.
Note that the raw buffer is DER encoded, and from crypto.publicEncrypt needs a PEM encoded key. So, you just need to do the conversion. I've used node-openssl-wrapper in the example below, but there are other libraries that also convert DER to PEM,
const ossl = require('openssl-wrapper')
const https = require("https");
https.request(options, res => {
const certificate = res.connection.getPeerCertificate();
const rawDer = certificate.raw;
ossl.exec('x509', rawDer, { inform: 'der', outform: 'pem' }, (err, buffer) => {
const publicKey = buffer.toString('utf8'); // PEM encoded public key safe to use now
// crypto.publicEncrypt({ key: publicKey, ...
})
});

Resources