node-rsa : InvalidAsn1Error: encoding too long - node.js

I am using node-rsa module for decrypt the key .
I have created one private key from p12 file by using below command
openssl pkcs12 -in xxx.p12 -nocerts -out privateKeyPkcs12.pem
it has given rsa private key so i have tried to create key by using this rsa private key like this
var NodeRSA = require('node-rsa');
var pemStr = '-----BEGIN RSA PRIVATE KEY-----\n' +
'ud5iSK4hAZo9DRi3/Xj7tYCb+AOv1rCAxWbM9KW959DaAYzO9eHRcmbO1Gusa93y\n' +
'2usgD3YYlfHAEvtMhW3KxDWXv0o/YE71pjltpn46qP0n2s78RwdbHONlXB0wk54Z\n' +
'1MqqZ8wxo/6mAu+ZqdCMe5rgOdMkXcHbFP+GFZQNSIoCrEQP098jhot9cYjyYNuW\n' +
'a7Y59gUEZE5s0jdrga/DcP+BUOfIoTZCf7gPqLQawjPXSp7Ddr5AxyVO8Phyp5yN\n' +
'hcdQV1Fvms5K7rsLvp0KFRz1iclrvBB5rYgawBSPGmrtP+AvRvjuDgfQiAPEA4SP\n' +
'cNx0oQ94q3jEPlhve86zhb1xDV4xnH8TKPYgpoafo6VC+w46FmoUh5/ZuKCsjBkV\n' +
'5gt3WyjsR5Jjgkv2pyH2rDfsB40DLvOg3GkgFo2gQ/UeXM3wQCjXRcG/rrlRYlj1\n' +
'9h+EjYaZE6vv+FpMLsYJc54bli/VjqyucEvvd0RuV15AEMI8cqwxlE3+ED2pv1Mk\n' +
'kLfONCAwylrvXBkapcp9P2qtRVLbyAzMXDJGDcSdxQFbDmmn8L/gOQs2+vgyvGet\n' +
'HxPC6gt1i6WEZHeQkSD68cs54JYmGZvu2bOTSCAMVOCKLv/Ed1LvSeowYZoHBXaK\n' +
'cRVqegBTWts5+DHWTwb8Nsrgz+5i6ZAFaJqGlrYjUApApDgAxTP5XQ47CxvtSg/T\n' +
'H25IJkY3Oz+7K18V1eslEk0bA44vYqeXia1ZLvLXRbtdSMlm0Fp7zTs7USVTJEgx\n' +
'RAGT8LnncwtZOFpEAYyIakI5lhe3aTvsDkW3pTXxDREKA2pmf0N7YAOw84tnoX8o\n' +
'w6hExfFrp2w82wRKft/ymoU5KUk6JSiHnuTu3JQPk/b9Vfb5zwRf5qXlLBERtO9U\n' +
'gctP2c3wvmF1pko8TfghKiTrAKi0Dft3Jrh50VDkmiFJCkupTDQ0EYyA4OV8PWui\n' +
'QhLFSGcBSGaik+7CMrh4TAiM59Hmh0Q3gKjmbvdYlx8gfZQzKWo71MkhDnbYTVnP\n' +
'6LU47Zo7ESFAPLFxBj0nTjJ8A7sFpQys/GK/fY29MnnR3LDT78zParNBKo56nCR4\n' +
'Sk8kL16Wx9hnTfEskHUKTmH9mph8hcv1S6/CQjQYVtLW13nlmGeAiJ/mf0sSzRhH\n' +
'mW5aCq3LAULIEpV0zRvpghZq4lc7RBbOudAgONrURWOgTgUxZ+N5PRMaesaeihpO\n' +
'gPY0LWyzb7CicK9y24oHO2uY87hinprusHaq/Rp4mVsYKRG0sk0/26bkbwn3sFMB\n' +
'LSSyGj32PD272bva1NE/4iWO+zppLKnroqUwrivmR3SPndvCX22x1qUiSY/R5UHp\n' +
'mcDWo9g9+nfPnXKmK2rwq82B4E+tqQZ68Iha95SaPYMt4pv+QPtaePxwSSpNPT9F\n' +
'WPwpEfKXa8wN9OAaGJBB9AM/Ry2aOTrekjNUxMzSqJdoBxsWxI0HrgVVaRQSk3VV\n' +
'juYMJdEjoSLY43jgZLEypA8ddmC55n/3Nwwyd6lkhvvkY+tvv6KL/zFnRQ81L0dP\n' +
'WTwvd33YSA6cCo4OEFixkls0lFq/MvesdXWZEyjNYzTlPYjqL9jIeik7VxQsw6sh\n' +
'-----END RSA PRIVATE KEY-----\n';
var key = new NodeRSA(pemStr);
console.log(key);
But i got this error
throw newInvalidAsn1Error('encoding too long');
^
InvalidAsn1Error: encoding too long
at module.exports.newInvalidAsn1Error (c:\Users\prabu\Desktop\project\node_modules\node-rsa\node_modules\asn1\lib\ber\errors.js:7:13)
at Reader.readLength (c:\Users\prabu\Desktop\project\node_modules\node-rsa\node_modules\asn1\lib\ber\reader.js:94:13)
at Reader.readSequence (c:\Users\prabu\Desktop\project\node_modules\node-rsa\node_modules\asn1\lib\ber\reader.js:127:16)
at NodeRSA.module.exports.NodeRSA.$loadFromPrivatePEM (c:\Users\prabu\Desktop\project\node_modules\node-rsa\src\NodeRSA.js:86:16)
at NodeRSA.module.exports.NodeRSA.loadFromPEM (c:\Users\prabu\Desktop\project\node_modules\node-rsa\src\NodeRSA.js:65:18)
at new NodeRSA (c:\Users\prabu\Desktop\project\node_modules\node-rsa\src\NodeRSA.js:35:18)
at Object.<anonymous> (c:\Users\prabu\Desktop\project\server.js:30:11)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
How to create key ?

Remove line feed (\n) at the end of the key string
'-----END RSA PRIVATE KEY-----\n';
to
'-----END RSA PRIVATE KEY-----';

Did you use passphrase? if yes, try to check is there any blank lines in you pass file.
Keep only the string, no more blank lines

Try to specify which standard your key is formatted in.
change this line by adding an additional parameter:
var key = new NodeRSA(pemStr);
to:
var key = new NodeRSA(pemStr, 'pkcs12');

Related

Subtle Crypto Importing PCKS RSA Key leads to ERR_OSSL_ASN1_WRONG_TAG

I'm trying out the subtle crypto methods in Node.js 18. I want to import a private RSA Key.
I copied the example straight from the MDN docs (https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/importKey#pkcs_8_import) and rewrote it to be able to run it in Node.js:
const { subtle } = require('crypto').webcrypto;
function str2ab(str) {
const buf = new ArrayBuffer(str.length);
const bufView = new Uint8Array(buf);
for (let i = 0, strLen = str.length; i < strLen; i++) {
bufView[i] = str.charCodeAt(i);
}
return buf;
}
// Example 2048 bit Key generated from https://travistidwell.com/jsencrypt/demo/
const pemEncodedKey = `-----BEGIN PRIVATE KEY-----
MIIEowIBAAKCAQBux5llZPW8B9b3n7lvw6wqeNUX/GKUB3iWN6FWWXRRlSdqvNkI2nGiiKE5lJv+ca507P/xPsj/ThmntnVPrwiN98FWlY8h7GPKAqPzzG+C+kOPpqvkZm10RHn/pjcdAi5QqBauMrZCis77x5O1ynJFu6DcDH/QM+0O4FCL+KHcahDhp/3Oc5O4cGDbGJcc8AsnD7d2Dv1yiFMDidKg2OuQIb/YvdxgO+DKB3Pjali3escD7b/Tj9iYQIhV3wEcXBFnenQGqz227bmtuRatyDgcOB5HL8k/YoxzTm7+1Qh2rhzJBe5zdZ86Ms7P7RPCg+od+wehzUowxWkxB372vWWfAgMBAAECggEAUxqRTKssXV5UOXctGVbk9QeodFH1ca8ZGzeoZKq+w+TsqPn6ptWYoaF1sUh2ra6CfVy9tDCxgDUKsfICl0BrXnUaKOYRdhVr1sOcUuxuSweLX1xdXv4n5izoiIwclDpqnD88pHmOmOSg2eiiOqIgj4dt6SXHTF1n3N0SD675XeuGmUVmNvw3V//FjpQqgAgVRsFoVI8rd3yxEeZRy/T8/lZWWQxt9232Ipcd91zHXFEvj+gQ8pAtyhLJ34dDJdT7Fs7eoDAkGqson1TedblGPbq+pieB59xGqciZgBQpcZNsfCuyzRA3skgd1Fu2NRnzgdDklKHnjEcUfib12nqTAQKBgQCyu77dAZezADejbCDxyRpHnGfp1Jz5p/Y/j9hvGEPl72aiFFZpD3Rbz3kPn9SayYVq5Zxjlt+KwuljNFppYeK0ZVZ2zWi1VmhrHwl+3yemf4ufltvCDCutDNLjjkt1rlwiz+eDmHSJiOFSEc5uJcFrwcAWDBKBQP1vn4VFqJ43fwKBgQCeq3tzAd/9W3ph7Dgv2ungimQ9vSZIfWawFnKyhfF5P7y8wJ6mgxnNv/BiuwqdqS5DY72EVq0tjwVvpHA6xCiWKYQ/9lhb9OJZsADbAaMRgKzuKCmpxJA2c6EKDQ2TK0/3WdLLnpuAXKcHP38sKJmKxm5wgRjC0pZLpWcK/xjh4QKBgQCEuxIxlAYxAz9OWHVauUqP1aIBr0fnywj/CPblAbMipZelU88b9EMoDzpLFRnQ3Uj8KonqF1fo93hUmMNvsSanav47+a0BxaqDqqfllRkf92Yb3O9T+q/Qsk5GeRymxxZbL+QxAN3CaWlTBjAz8kvilx7sAIkZfcb3xxI0udTNRwKBgD664SWI2jtaTToln9kbnVdOn27hNx91pIF9fn8iAWPEVSPyq0Z9klgLyEfgVsQaPNYburN1aSYX4zhONKinILytUUHQbQJ+AHcg5FWxgfzLeJL3gfFCaxl8AXDt1C4Y85aBBpvF6wiGmOp+qhKVQo7hAIyuHVH4276wd9qbHAVBAoGBAIqjXYfmtHRONXVtMCt5rlt3Y/Pe0KkA6vvfjGMnRKrmvEsHXh8Aj9ZPiTDxBKweJggg9BoJ/bs3juENIx5cJ76aiBYsdhw+4IGF79IfZm73k2ZC9exy9m69yp7GszmdZVJuiFlRoJFBMQm6oDH1+tUPW9M/76Ah8GpjkWx6dAcr
-----END PRIVATE KEY-----`;
const importPrivateKey = async () => {
const pemHeader = "-----BEGIN PRIVATE KEY-----";
const pemFooter = "-----END PRIVATE KEY-----";
const pemContents = pemEncodedKey.substring(pemHeader.length, pemEncodedKey.length - pemFooter.length);
const binaryDerString = Buffer.from(pemContents, 'base64').toString('binary');
const binaryDer = str2ab(binaryDerString);
const key = await subtle.importKey(
"pkcs8",
binaryDer,
{
name: "RSA-OAEP",
hash: "SHA-256",
},
true,
["decrypt"]
);
}
importPrivateKey();
Now when I run this file, I get:
node:internal/crypto/keys:618
handle.init(kKeyTypePrivate, data, format, type, passphrase);
^
Error: error:0D0680A8:asn1 encoding routines:asn1_check_tlen:wrong tag
at createPrivateKey (node:internal/crypto/keys:618:12)
at Object.rsaImportKey (node:internal/crypto/rsa:270:19)
at SubtleCrypto.importKey (node:internal/crypto/webcrypto:513:10)
at importPrivateKey (/Users/felix/Desktop/fts/js-api/bin/test.js:23:28)
at Object.<anonymous> (/Users/felix/Desktop/fts/js-api/bin/test.js:35:1)
at Module._compile (node:internal/modules/cjs/loader:1105:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
at Module.load (node:internal/modules/cjs/loader:981:32)
at Module._load (node:internal/modules/cjs/loader:827:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:77:12) {
opensslErrorStack: [
'error:0D08303A:asn1 encoding routines:asn1_template_noexp_d2i:nested asn1 error',
'error:0D07803A:asn1 encoding routines:asn1_item_embed_d2i:nested asn1 error'
],
library: 'asn1 encoding routines',
function: 'asn1_check_tlen',
reason: 'wrong tag',
code: 'ERR_OSSL_ASN1_WRONG_TAG'
}
This example does work when I use the key from the linked MDN docs. But not if I use a freshly generated one.
What is going wrong here?
Your private key is inconsistent: You use the header and footer of a PKCS#8 key, but the body of a PKCS#1 formatted key. This can be verified e.g. in an ASN.1 parser like https://lapo.it/asn1js/.
Note that the JSEncrypt demo generates a PKCS#1 formatted private key (inclusive PKCS#1 header and footer).
Since WebCrypto API does not support PKCS#1 (see here), you need to convert the key to a PKCS8 formatted key, e.g. with OpenSSL.
Your key in PKCS#8 format (without line breaks in the body, so it can be used directly in JavaScript code) is:
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAG7HmWVk9bwH1vefuW/DrCp41Rf8YpQHeJY3oVZZdFGVJ2q82QjacaKIoTmUm/5xrnTs//E+yP9OGae2dU+vCI33wVaVjyHsY8oCo/PMb4L6Q4+mq+RmbXREef+mNx0CLlCoFq4ytkKKzvvHk7XKckW7oNwMf9Az7Q7gUIv4odxqEOGn/c5zk7hwYNsYlxzwCycPt3YO/XKIUwOJ0qDY65Ahv9i93GA74MoHc+NqWLd6xwPtv9OP2JhAiFXfARxcEWd6dAarPbbtua25Fq3IOBw4HkcvyT9ijHNObv7VCHauHMkF7nN1nzoyzs/tE8KD6h37B6HNSjDFaTEHfva9ZZ8CAwEAAQKCAQBTGpFMqyxdXlQ5dy0ZVuT1B6h0UfVxrxkbN6hkqr7D5Oyo+fqm1ZihoXWxSHatroJ9XL20MLGANQqx8gKXQGtedRoo5hF2FWvWw5xS7G5LB4tfXF1e/ifmLOiIjByUOmqcPzykeY6Y5KDZ6KI6oiCPh23pJcdMXWfc3RIPrvld64aZRWY2/DdX/8WOlCqACBVGwWhUjyt3fLER5lHL9Pz+VlZZDG33bfYilx33XMdcUS+P6BDykC3KEsnfh0Ml1PsWzt6gMCQaqyifVN51uUY9ur6mJ4Hn3EapyJmAFClxk2x8K7LNEDeySB3UW7Y1GfOB0OSUoeeMRxR+JvXaepMBAoGBALK7vt0Bl7MAN6NsIPHJGkecZ+nUnPmn9j+P2G8YQ+XvZqIUVmkPdFvPeQ+f1JrJhWrlnGOW34rC6WM0Wmlh4rRlVnbNaLVWaGsfCX7fJ6Z/i5+W28IMK60M0uOOS3WuXCLP54OYdImI4VIRzm4lwWvBwBYMEoFA/W+fhUWonjd/AoGBAJ6re3MB3/1bemHsOC/a6eCKZD29Jkh9ZrAWcrKF8Xk/vLzAnqaDGc2/8GK7Cp2pLkNjvYRWrS2PBW+kcDrEKJYphD/2WFv04lmwANsBoxGArO4oKanEkDZzoQoNDZMrT/dZ0suem4Bcpwc/fywomYrGbnCBGMLSlkulZwr/GOHhAoGBAIS7EjGUBjEDP05YdVq5So/VogGvR+fLCP8I9uUBsyKll6VTzxv0QygPOksVGdDdSPwqieoXV+j3eFSYw2+xJqdq/jv5rQHFqoOqp+WVGR/3Zhvc71P6r9CyTkZ5HKbHFlsv5DEA3cJpaVMGMDPyS+KXHuwAiRl9xvfHEjS51M1HAoGAPrrhJYjaO1pNOiWf2RudV06fbuE3H3WkgX1+fyIBY8RVI/KrRn2SWAvIR+BWxBo81hu6s3VpJhfjOE40qKcgvK1RQdBtAn4AdyDkVbGB/Mt4kveB8UJrGXwBcO3ULhjzloEGm8XrCIaY6n6qEpVCjuEAjK4dUfjbvrB32pscBUECgYEAiqNdh+a0dE41dW0wK3muW3dj897QqQDq+9+MYydEqua8SwdeHwCP1k+JMPEErB4mCCD0Ggn9uzeO4Q0jHlwnvpqIFix2HD7ggYXv0h9mbveTZkL17HL2br3KnsazOZ1lUm6IWVGgkUExCbqgMfX61Q9b0z/voCHwamORbHp0Bys=
-----END PRIVATE KEY-----
With this key format the JavaScript code works and the key is imported correctly.
By the way, under NodeJS you can use Buffer directly, i.e. the conversion via a binary string into an ArrayBuffer and thus also str2ab() are not needed:
...
const binaryDer = Buffer.from(pemContents, 'base64');
const key = await subtle.importKey(
"pkcs8",
binaryDer,
{
name: "RSA-OAEP",
hash: "SHA-256",
},
true,
["decrypt"]
);
...
Note that even under v18.1.0, the WebCrypto API is marked Stability: 1 - Experimental (here).

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-forge self signed certificate for https module

OS: Windows 10
Node.js version: node-v8.11.4-win-x64
node-forge version: 0.7.7-dev
People,
i'm having a hard time trying to create an node.js https server.
The idea behind the server is that it's only for local loopback requests.
With it in mind and for the sake of privacy i thought of disposable self signed certificates renewed at each server restart.
Following suggestions i'm trying to use the node-forge module to generate the disposable certificates.
Reading their instructions at https://www.npmjs.com/package/node-forge i came with a very simple code:
var https = require('https');
var forge = require('node-forge');
forge.options.usePureJavaScript = true;
var pki = forge.pki;
var keys = pki.rsa.generateKeyPair(2048);
var cert = pki.createCertificate();
cert.publicKey = keys.publicKey;
cert.serialNumber = '01';
cert.validity.notBefore = new Date();
cert.validity.notAfter = new Date();
cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear()+1);
var attrs = [
{name:'commonName',value:'example.org'}
,{name:'countryName',value:'US'}
,{shortName:'ST',value:'Virginia'}
,{name:'localityName',value:'Blacksburg'}
,{name:'organizationName',value:'Test'}
,{shortName:'OU',value:'Test'}
];
cert.setSubject(attrs);
cert.setIssuer(attrs);
cert.sign(keys.privateKey);
var pem_pkey = pki.publicKeyToPem(keys.publicKey);
var pem_cert = pki.certificateToPem(cert);
console.log(pem_pkey);
console.log(pem_cert);
https.createServer( { key:pem_pkey, cert:pem_cert },(req,res)=>
{
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(443);
then it emits an error i make absolutely no idea what's about:
E:\forge_case\node-v8.11.4-win-x64>node.exe index.js
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkTmxd1fWK+XL2Cp5+n82
mSe6iqM3qvwMEC+pIAlhpbangujOzKghnJaX4QsmBBBumNRN3zR2UOUAeYHmPS8v
3dbmgStB023aiFJ82ozewuGlykdQUFxWfR+OUA3xZcFZ7Ma+67tSJNtnkW4wNhzR
XImTCHYknu2dBAm7V2tGZKq/ZrKnY+f1VTW9t3jpw55ACjsFkMfqUenfDDAVFMwm
NnRpX1ecyVd2TEoeQ95k+q4Exm5AbxuqVMXVKHXMNZlq2ftG8tcrYS95Z3cAakVm
sxX8/BMZGZILG/30fdLPL8bZqGV+BXzz2AJ0egKLivunPtRpyI+Id0v1jYsrZ/9L
YwIDAQAB
-----END PUBLIC KEY-----
-----BEGIN CERTIFICATE-----
MIIDSzCCAjOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBpMRQwEgYDVQQDEwtleGFt
cGxlLm9yZzELMAkGA1UEBhMCVVMxETAPBgNVBAgTCFZpcmdpbmlhMRMwEQYDVQQH
EwpCbGFja3NidXJnMQ0wCwYDVQQKEwRUZXN0MQ0wCwYDVQQLEwRUZXN0MB4XDTE4
MDgyMTE5Mzk1N1oXDTE5MDgyMTE5Mzk1N1owaTEUMBIGA1UEAxMLZXhhbXBsZS5v
cmcxCzAJBgNVBAYTAlVTMREwDwYDVQQIEwhWaXJnaW5pYTETMBEGA1UEBxMKQmxh
Y2tzYnVyZzENMAsGA1UEChMEVGVzdDENMAsGA1UECxMEVGVzdDCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBAJE5sXdX1ivly9gqefp/NpknuoqjN6r8DBAv
qSAJYaW2p4LozsyoIZyWl+ELJgQQbpjUTd80dlDlAHmB5j0vL93W5oErQdNt2ohS
fNqM3sLhpcpHUFBcVn0fjlAN8WXBWezGvuu7UiTbZ5FuMDYc0VyJkwh2JJ7tnQQJ
u1drRmSqv2ayp2Pn9VU1vbd46cOeQAo7BZDH6lHp3wwwFRTMJjZ0aV9XnMlXdkxK
HkPeZPquBMZuQG8bqlTF1Sh1zDWZatn7RvLXK2EveWd3AGpFZrMV/PwTGRmSCxv9
9H3Szy/G2ahlfgV889gCdHoCi4r7pz7UaciPiHdL9Y2LK2f/S2MCAwEAATANBgkq
hkiG9w0BAQUFAAOCAQEAgTGiTF6BDLX3w1PfJxXYYzVBoN8NlL979mcfRVhvLH/N
lEaaQvGhDSrp97s9K0kEw3A16WzUwnysoX1uOdlHHp78v2tXaffDzXTnH75CN4pd
qNHuy05AFIoiBujZR67OR4ipcKZ9USYz0QZysMFyzCxum2btLPvrs+onIxdvsuA+
Xe9vFxj+AJ4hv03tDuQXj+pZ2dflWyy5ZdaMDeUjWtSK9MHPn6rs5Fs340B4NnxL
3Y6RKDj4CerGbtufR73UNirNfmbqiAybZ6vG1RaL2oBiHdoJfpB/FLm7QFn34apq
A1Kd1VPShBC4G/4S+0E6U84D4xNJcjT6NfzDGBD6Ng==
-----END CERTIFICATE-----
_tls_common.js:104
c.context.setKey(options.key, options.passphrase);
^
Error: error:0906D06C:PEM routines:PEM_read_bio:no start line
at Object.createSecureContext (_tls_common.js:104:17)
at Server (_tls_wrap.js:805:25)
at new Server (https.js:54:14)
at Object.createServer (https.js:76:10)
at Object.<anonymous> (E:\forge_case\node-v8.11.4-win-x64\index.js:33:7)
at Module._compile (module.js:652:30)
at Object.Module._extensions..js (module.js:663:10)
at Module.load (module.js:565:32)
at tryModuleLoad (module.js:505:12)
at Function.Module._load (module.js:497:3)
Any ideas? thanks!
var pem_pkey = pki.priateKeyToPem(keys.privateKey);

node crypto: en/decrypt token for validation

I want to en- and decrypt a token to be able to determine if it could be a valid token without accessing the DB.
My code is working for tokens that look "completely different" but if I only change one letter, a result is returned (no error thrown) thus looking like the token is valid ...!?
This is my code (plus changing the letter manually):
var crypto = require("crypto");
var cryptSecret = "a!=ksljdk34ajSDkl";
var token = "1d3889647173d415e24195ce5cafc36c1edcc053";
function _encodeUrlSaveBase64(str) {
return str.replace(/\+/g, "-").replace(/\//g, "_").replace(/\=+$/, "");
}
function _decodeUrlSaveBase64(str) {
str = (str + "===").slice(0, str.length + (str.length % 4));
return str.replace(/-/g, "+").replace(/_/g, "/");
}
function _encrypt(data) {
var cipher = crypto.createCipher("aes256", cryptSecret);
var str = cipher.update(data, "utf8", "base64") + cipher.final("base64");
str = _encodeUrlSaveBase64(str);
return str;
}
function _decrypt(data) {
var str = _decodeUrlSaveBase64(data);
var decipher = crypto.createDecipher("aes256", cryptSecret);
str = decipher.update(str, "base64", "utf8") + decipher.final("utf8");
return str;
}
console.log("token: ", token);
var encrypted = _encrypt(token);
console.log("encrypted:", encrypted);
// change fourth letter to upper-case B (instead of lower-case)
encrypted = "bYzBYnU8FX7Rxs6Hae-yZkXvlwlRnhMQdLrT07e6YBy79nrK8FIpbKbxsYsXUmbk";
console.log("changed :", encrypted);
console.log("decrypt :", _decrypt(encrypted));
and it outputs:
token: 1d3889647173d415e24195ce5cafc36c1edcc053
encrypted: bYzbYnU8FX7Rxs6Hae-yZkXvlwlRnhMQdLrT07e6YBy79nrK8FIpbKbxsYsXUmbk
changed : bYzBYnU8FX7Rxs6Hae-yZkXvlwlRnhMQdLrT07e6YBy79nrK8FIpbKbxsYsXUmbk
decrypt : �g�
1��/b���e2.195ce5cafc36c1edcc053
where it should normally throw an error like this:
TypeError: error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt
at Decipher.Cipher.final (crypto.js:302:27)
at _decrypt (/***/test.js:25:59)
at Object.<anonymous> (/***/test.js:35:27)
at Module._compile (module.js:449:26)
at Object.Module._extensions..js (module.js:467:10)
at Module.load (module.js:349:32)
at Function.Module._load (module.js:305:12)
at Function.Module.runMain (module.js:490:10)
at startup (node.js:123:16)
at node.js:1128:3
Am I doing anything wrong or is this just the way this works?
You need to distinguish between encryption (hide something) and signing (validate something). In your case you are hiding the content of the token. A simple solution for validating a token is a hash using a secret:
hashvalue = tokenvalue + hashfunction(tokenvalue + secret)
When validating, cut out the tokenvalue and calculate the hashvalue again, if it does not match someone must have tampered the token. A popular example of this is LTPA v1.
This scheme has some shortcomings, the biggest would be that every party needs the secret to validate the tokens and is therefore able to create a new valid token. IBM switched to public key for LTPA v2 because of this.

node.js digital signature does not work

I am trying to generate a digital signature using the crypto module for node.js (0.6.15). The following code prints nothing (on both a windows and a linux machine) and res is of length 0. Also signer never throws an exception no matter what dummy input I give as key. openssl is installed in version 1.0.1. What am I doing wrong?
var crypto = require('crypto');
var signer = crypto.createSign("RSA-SHA1")
signer.update("sign me!")
//dummy key
var private_key = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAL4vpoH3H3byehjj" +
"7RAGxefGRATiq4mXtzc9Q91W7uT0DTaFEbjzVch9aGsNjmLs4QHsoZbuoUmi0st4" +
"x5z9SQpTAKC/dW8muzacT3E7dJJYh03MAO6RiH4LG34VRTq1SQN6qDt2rCK85eG4" +
"5NHI4jceptZNu6Zot1zyO5/PYuFpAgMBAAECgYAhspeyF3M/xB7WIixy1oBiXMLY" +
"isESFAumgfhwU2LotkVRD6rgNl1QtMe3kCNWa9pCWQcYkxeI0IzA+JmFu2shVvoR" +
"oL7eV4VCe1Af33z24E46+cY5grxNhHt/LyCnZKcitvCcrzXExUc5n6KngX0mMKgk" +
"W7skZDwsnKzhyUV8wQJBAN2bQMeASQVOqdfqBdFgC/NPnKY2cuDi6h659QN1l+kg" +
"X3ywdZ7KKftJo1G9l45SN9YpkyEd9zEO6PMFaufJvZUCQQDbtAWxk0i8BT3UTNWC" +
"T/9bUQROPcGZagwwnRFByX7gpmfkf1ImIvbWVXSpX68/IjbjSkTw1nj/Yj1NwFZ0" +
"nxeFAkEAzPhRpXVBlPgaXkvlz7AfvY+wW4hXHyyi0YK8XdPBi25XA5SPZiylQfjt" +
"Z6iN6qSfYqYXoPT/c0/QJR+orvVJNQJBANhRPNXljVTK2GDCseoXd/ZiI5ohxg+W" +
"UaA/1fDvQsRQM7TQA4NXI7BO/YmSk4rW1jIeOxjiIspY4MFAIh+7UL0CQFL6zTg6" +
"wfeMlEZzvgqwCGoLuvTnqtvyg45z7pfcrg2cHdgCXIy9kErcjwGiu6BOevEA1qTW" +
"Rk+bv0tknWvcz/s="
var res = signer.sign(private_key, output_format='base64')
console.log(res);
As Ben Noordhuis tells me here the key used above is not in the correct format. it is best to load the pem format from disk.

Resources