node-rsa and openssl compatibility - node.js

I have a set of public/private keys, that works flawless when encrypting/decrypting some data using only one of the 2 ways for both encryption and decryption.
I still have no luck trying to encrypt the data with the one of the two and decrypt it with the other.
Example schenario:
a) I create some encrypted data using the public key with the following node.js code:
#!/usr/bin/env node
var NodeRSA = require('node-rsa');
var fs = require('fs');
function createUsingPubKey(Pub, data) {
var pk = new NodeRSA();
pk.importKey(Pub);
encrypted = pk.encrypt(data, 'base64');
return encrypted;
}
var sampledata = "SECRET STUFF";
var genkey = createUsingPubKey(fs.readFileSync('id_rsa.pub'), sampledata)
console.log(genkey);
b) Then i try to decrypt it using openssl utility with this:
node test.js | openssl base64 -d -A | openssl rsautl -inkey id_rsa
But i get:
RSA operation error
1068:error:0406706C:rsa routines:RSA_EAY_PUBLIC_DECRYPT:data greater than mod len:.\crypto\rsa\rsa_eay.c:680:
I thought that they probably would use different algorithms for the encryption/decryption procedure so i headed to the node-rsa documentation here:
https://www.npmjs.com/package/node-rsa and i found this option:
encryptionScheme — padding scheme for encrypt/decrypt. Can be
'pkcs1_oaep' or 'pkcs1'. Default 'pkcs1_oaep'.
I then tried to decrypt passing the -oaep option in openssl util like this:
node test.js | openssl base64 -d -A | openssl rsautl -oaep -inkey id_rsa
But i still get:
RSA operation error
5216:error:0406706C:rsa routines:RSA_EAY_PUBLIC_DECRYPT:data greater than mod len:.\crypto\rsa\rsa_eay.c:680:
My knowledge on cryptography is really basic. Any help would be appreciated :)
EDIT 1:
The node.js module can be found here:
https://github.com/rzcoder/node-rsa
EDIT 2:
As Maarten Bodewes requested, here is some sample data:
Plaintext data to be encrypted:
You're no good, you're no good, you're no good Baby, you're no good
(I'm gonna say it again) You're no good, you're no good, you're no
good Baby, you're no good
A private key generated with
openssl genrsa -out key 512
-----BEGIN RSA PRIVATE KEY-----
MIIBOgIBAAJBALOUBygyX11BsDoEIKoZzn2/HAXPorNR/X8wCDaBlcPtOHxKAZFk
Vra1+Pem1urtSlnEqc07DwAP6v0GEGHpxbkCAwEAAQJAGAZ17qrOl2tyaFClDhzl
w20OErj0y4jsoVeLwb8UimG48JslS14hfM9XxE/fG6qypN8u7LUhlnBC68ZcQ9Jg
AQIhAORaVlB7trWp6n7dETvdY9J2p8ubOuyLTX0BA2jF8agxAiEAyVHzDWQPWx/s
gt+ABErqN+ZUWS016DD34QUVGyp9nAkCIQC39JpSDcd7gx1YA8jNXCT9N/8mg6+t
PO84g2d2sPdjEQIgXwWMF/TzfopJ4tfFH8GQXYQcqd66A/cg+Jeih6j9kqkCIGD4
hBAO0haqnqeSO65Mm1IjY/6Z77pKxzJAGys5XeXk
-----END RSA PRIVATE KEY-----
And its equivalent pub key
openssl rsa -in key -pubout > key.pub
-----BEGIN PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALOUBygyX11BsDoEIKoZzn2/HAXPorNR
/X8wCDaBlcPtOHxKAZFkVra1+Pem1urtSlnEqc07DwAP6v0GEGHpxbkCAwEAAQ==
-----END PUBLIC KEY-----
The above plaintext data encrypted with the given public key using the node.js rsa library:
nbp1tBlcev9PvD3xDmEQkcBd8ewNxW8Xm7oZWVcsFika3dU/H3VFoxdeH75DPy4/xLvN1Gxqfb/bXTnfKZLZBYV1q4XfmR4p3ji41MAybpMiEl5h4fSFYacg5SiQ/KxxmQr0SLs4rttwcbaGBLG6rcIU+6SSYBYu1GhC+XBlBG94zbqFV9ZvohEbnlnqDDW1Kg9hGT9/vBBtiLEQnTiKDwztIgY3DhqadsVW0g37PFFwuQKXtHw/lQqrRhc+Pb03g+Oq8nIpX8eaurL8lo3lZNkhlY4NfFCYwP7v12MYwSrMeWPMe20LDDQ6NXbJnrsLGl5x08aYn7liS5qsYdtqRpYv+JbJc3EoXIZEyHv17gU1R0OmLsSd/Teln9VAvM+jt4jwQjlvE1WF8g9Qc/WNo28RR4KaNOvUpLDwfuc3gTgkG90ac8EchmKB3LAgU47kQComyphuPAI/G4phqeXOeYnbBrB1aqwxAkAwOIvanGjCY6FXlV8Cve1jao0ejQ0EFE1180yjhltgh5U2EErQLDd5S4y5YLbLz4xIiKo3k06Yktk4dSJsBalHPxi7Z+kofjT3KdeHyGMynodGzOmH5CaAAS2enZpp2VytcawlDu84EvrPYIRPWah9cA6dtxARx6us8EytrNIDv7UVGXw/cQEPR1nZamz6HROqT4Fpwfc=

Just add -decrypt argument for openssl
node test.js | openssl base64 -d -A | openssl rsautl -decrypt -oaep -inkey id_rsa
works pretty nice for me.

Related

how to achieve openssl smime encrypt with public key functionality in code

I am encrypting a file with this openssl command -
openssl smime -encrypt -aes256 -in <input-file> -binary -outform DEM publicKey.pem
Although the command uses public key but it does not uses RSA as the input file is certainly larger in size.
The same file can be decrypted by -
cat encrypted | openssl smime -decrypt -binary -inform DEM -inkey publickey.pem
My question is, what method openssl uses here to encrypt using public key and how to achieve this command line functionality in code using node.js / ruby ?

Decrypting file from crypto module using openssl

I have a use case where we're streaming log data to a file using a simple NodeJS app. We'd like to be able to encrypt this data as we're streaming it and then decrypt it later as required using OpenSSL or similar.
What we're doing a basically as below:
var crypto = require('crypto'),
algorithm = 'aes256',
password = 'password';
var fs = require('fs');
var Readable = require('stream').Readable
var r = new Readable
r.push('This is a test')
r.push(null)
var encrypt = crypto.createCipher(algorithm, password);
var decrypt = crypto.createDecipher(algorithm, password)
var w = fs.createWriteStream('file.out');
//Write encrypted stream to file. Decrypt with openssl fails with 'bad magic number'
r.pipe(encrypt).pipe(w)
//Decrypt using cipher library. Decrypted text displays as expected
//r.pipe(encrypt).pipe(decrypt).pipe(w)
Assuming we're just encrypting the data as we're reading it in I'd assumed we could decrypt it using open OpenSSL e.g.
openssl enc -d -aes256 -in file.out -out file.out.decrypted
But this is just giving me the error
Bad magic number
Any help would be really appreciated.
Looking at the documentation of the crypto.createCipher() function, it mentions that the OpenSSL EVP_BytesToKey() function is used for deriving the key from the passphrase, just like the openssl enc app does. So that seems compatible.
However, that same documentation does not mention that any salt is applied and the function does not seem to have the possibility to pass a salt in as a parameter either. Therefore, you will have to pass the -nosalt option to openssl enc to make it work, as in:
openssl enc -d -aes256 -nosalt -in file.out -out file.out.decrypted
You can simulate what is happening by just using the openssl enc tool, with and without expecting a salt on the decrypt end:
Your current situation:
$ echo -n 'This is a test' | openssl enc -aes256 -nosalt -pass pass:password | openssl enc -d -aes256 -pass pass:password
bad magic number
Adding -nosalt when decrypting:
$ echo -n 'This is a test' | openssl enc -aes256 -nosalt -pass pass:password | openssl enc -d -aes256 -nosalt -pass pass:password
This is a test
By default, the OpenSSL encrypted file format starts with an 8-byte "magic number", the US-ASCII encoding of "Salted__". That's followed by another 8-byte value that's hashed with the password to derive the encryption key and IV for the message. Your NodeJS code isn't deriving the key the same way or providing the necessary header, so it won't work.
OpenSSL's key derivation algorithm is insecure and non-standard. If you derive the key from a password yourself using a good key derivation algorithm like PBKDF2 (or, better yet, randomly choose a key), you can provide it (encoded in hexadecimal) to the enc command with the -K option, along with the IV using the -iv option. I haven't checked to see if you also need the -nosalt option to avoid complaints about the magic number in this case.

Openssl ECDSA : private key passphrase

I am new with Openssl i have generated a private key myprivatekey.pem and a publickey mypublickey.pem with :
openssl ecparam -genkey -name secp160k1 -noout -out myprivatekey.pem
and my public key with :
openssl -ec -in myprivatekey.pem -pubout -out mypublickey.pem
What i want to do next is to encrypte my ecdsa with a passphrase private key and make a certification request for my public key and thank you for your help.
It would seem that ecparam doesn't have a built-in option for encrypting the generated key. Instead, you can simply do the following:
openssl ec -in myprivatekey.pem -out myprivatekey_encrypted.pem -aes256
Compared to genrsa, an extra step is required, but this basically does the same thing.
Now as far as the certificate request, the command is pretty much the same regardless of the type of private key used:
openssl req -new -sha256 -key myprivatekey.pem -out mycertrequest.pem
You can then take the resulting mycertrequest.pem and send it to a CA for signing.
Edit:
If you have concerns about writing the unencrypted private key to disk, you can do both the generation and encryption of the key in one step like so:
openssl ecparam -genkey -name secp256k1 | openssl ec -aes256 -out privatekey.pem
This generates a P-256 key, then prompts you for a passphrase. The key is then encrypted using AES256 and saved into privatekey.pem.
While ecparam doesn't have an option to encrypt the generated key, genpkey can generate ECC private keys and does have such an option:
openssl genpkey -algorithm ec -pkeyopt ec_paramgen_curve:secp160k1 -aes-256-cbc -out myprivatekey_encrypted.pem
The -aes-256-cbc option specifies to encrypt it (with aes-256-cbc; other options are available for different types of encryption).
You can pass -passin pass:password or -passin file:mypassword.pass to specify the password on the commandline.

openssl/RSA - Using a Public key to decrypt

I'm looking to secure the software update procedure for a little device I'm maintaining that runs Linux. I want to generate an md5sum of the update package's contents and then encrypt that hash with a private key before sending it out to the customer. When they load the update, the device should then decrypt the hash, verify it, and proceed with installation of the package.
I'm trying to do this with OpenSSL and RSA. I found this thread, and was discouraged. I then found this thread and wondered how Perl gets around the purported impossibility of it all. I'm doing this in C, so perhaps there's a parallel function in an SSL library somewhere?
So my question really is: can I force command line Linux to take a public key as the decryption input, or perhaps use C to circumvent that limitation?
Thanks in advance, all.
Let's assume you have generated a public and private RSA key using openssl genrsa:
$ openssl genrsa -out mykey
Generating RSA private key, 512 bit long modulus
...++++++++++++
..........++++++++++++
e is 65537 (0x10001)
$ openssl rsa -in mykey -pubout -out mykey.pub
writing RSA key
You can sign something with the private key like this:
$ md5sum myfile | openssl rsautl -inkey mykey -sign > checksum.signed
You can verify this data using the public key:
$ openssl rsautl -inkey mykey.pub -pubin -in checksum.signed
df713741d8e92b15977ccd6e019730a5 myfile
Is this what you're looking for?
NOTE: I recommend you use the sign and verify routines instead of trying to implement them yourself with the underlying RSA encrypt and decrypt routines.
Nonetheless, Openssl CLI can achieve "decrypting with the public key" via the rsautl subcommand like so:
openssl rsautl -verify -inkey public_key.pem -pubin -in data.sig -raw -hexdump

How to encrypt and decrypt xml using openSSL with public key

Can any one able to tell me how to encrypt and decrypt a xml file using openssl. I can able to create privatekey using the Linux command
openssl genrsa -out private.pem 1024
And got my private key as private.pem. Created public key using
openssl rsa -in private.pem -out public.pem -outform PEM -pubout
got my public key as public.pem
Now what I want is I want to encrypt the XML file using this public key and again want to decrypt using my private key.
Try:
$ openssl rsautl -encrypt -inkey public.pem -pubin -in file.xml -out file.xml.encrypted
Hint: I cheated and looked here:
http://www.devco.net/archives/2006/02/13/public_-_private_key_encryption_using_openssl.php

Resources