How to encrypt in node.js and decrypt with RNCryptor - commoncrypto

I'm having trouble encrypting data with node and decrypting with RNCryptor. My understanding is that RNCryptor uses a special data format?
The cryptotext is being generated as follows:
var crypto = require('crypto');
var cipher = crypto.createCipher('aes-256-cbc','InmbuvP6Z8');
var text = "123|123123123123123";
var crypted = cipher.update(text,'utf8','base64');
crypted += cipher.final('base64');
And I'm decrypting like this:
[RNDecryptor decryptData:plainText withPassword:password error:&error];
How am I supposed to do this? When I try to decrypt currently I get an empty NSData and no error.

Yes, RNCryptor outputs encrypted data in its own format. If you build this format in your own encryption code (and use the same encryption params), you can pass it to JNCryptor to decrypt.
For RNCryptor format version 3, the first 34 bytes are as follows:
byte[0] is the version (3).
byte[1] defines whether a password or a key is used (1 for password, 0 for key).
bytes[2-9] carry the encryption salt.
bytes[10-17] carry the HMAC salt.
bytes[18-33] carry the IV.
Then comes the encrypted ciphertext.
Then the last 32 bytes hold the (SHA256) HMAC for the ciphertext.
The spec is here: https://github.com/RNCryptor/RNCryptor-Spec/blob/master/RNCryptor-Spec-v3.md

RNCryptor is more than just encryption, it is an entire secure "stack" including authentication, password key derivation, versioning and random iv. Since your encryption is just the encryption portion it will be incompatible.
Either use RNCryptor for the encryption or change to a simple decryption method. Since the question has a commoncrypto tag and the encryption code look like it might be Swift (there is no language tag) just consider using Common Crypto in Objective-C for the decryption. See the SO answer for example code.

Related

Data Encryption Keys and Key Encryption Keys

I hope someone can help me to understand how DEK and KEK works in layman term.
This is my understanding so far
Part 1
Uploaded data is stored in chunks. Each chunk is encrypted with DEK. DEK is stored near the chunked data.
Part 2 DEK of the data chunk is wrapped with KEK
Part 3 KEK is stored in KMS.
This sentence from a Google's course material really tripped me.
The wrapped data encryption keys are then stored with this data
My brain goes crazy with these questions:
What is this wrapped data encryption keys? Isn't that the KEK in part 2?
If that's the KEK in part 2, shouldn't that be in KMS?
If yes, does KMS store data?
If no, how many DEKs a chunk of data has? 2 DEKs?
What keys do we(users/customers)keep?
We store the data with which keys?
What is this wrapped data encryption keys? Isn't that the KEK in part 2?
The wrapped DEK is the result of encrypting the DEK with the KEK. The key encryption key is called that because it encrypts (data encryption) keys.
If that's the KEK in part 2, shouldn't that be in KMS?
Does KMS store data?
No. As the name suggests, a key management system only stores keys, and specifically KEKs.
How many DEKs does a chunk of data have? 2 DEKs?
One. Data is encrypted only once, so there is only one key.
What keys do we (users/customers) keep?
Only the KEK. When using a KMS, not even that key is known to you, the user of the KMS.
We store the data with which keys?
With the wrapped DEK.
Here is a concrete example:
Data (i.e. plaintext): yellow submarine
KEK (aka. master key): my-secret-master
DEK (randomly generated for each piece of data): ttlly-random-dek
Ciphertext: Base64(AES(Data, DEK)) = TJ4SLFTy0sMdvGe55QCuYQ==
Wrapped DEK: Base64(AES(DEK, KEK)) = lOEmql1JuSONZ8uLorc/vQ==
The second operation is done by the KMS, if there is one (it has to be, because it's the only one in possession of the KEK, and it will never disclose it).
What you store together: TJ4SLFTy0sMdvGe55QCuYQ== and lOEmql1JuSONZ8uLorc/vQ==.
And to reconstruct the plaintext given TJ4SLFTy0sMdvGe55QCuYQ== + lOEmql1JuSONZ8uLorc/vQ==:
DEK: AES'(Base64'(lOEmql1JuSONZ8uLorc/vQ==), KEK) // = ttlly-random-dek Plaintext: AES'(Base64'(TJ4SLFTy0sMdvGe55QCuYQ==), DEK)
The first operation is done by the KMS if there is one (again, it has to be, because the KEK is involved).
In the example above I conveniently chose 16 bytes of data and 16-byte keys, so I could gloss over block cipher modes and IVs/nonces. In practical applications the IVs for each encryption have to be retained as well, of course.
Note that the KMS never sees your data, and it only has to encrypt and decrypt tiny amounts. That is why we do all of this; only you, the owner of the data ever sees it in plaintext (assuming the KMS is an honest party, obviously).

What format is this 128 bit AES key specified with in this example?

I am referencing this gist available online.
It's using a hard-coded 128 bit AES key to encrypt/decrypt data. The key is hard-coded in this format:
wchar_t default_key[] = L"3igcZhRdWq96m3GUmTAiv9";
How is a 128 bit AES key specified in this format? And how would I, for example, specify/convert an AES 256 key in raw hex form (like shown below) in the same format:
5DD34BE0C9C344833C91E20D247C3B2988340A034C9719C7C291EC2F781F8133
Note that all keys shown here are just examples and not used to encrypt any sensitive information.
It is likely that the hardcoded key is a base64 encoded 128-bit key without padding. But it is also possible that it is arbitrary UTF8 that is padded to become the 128 bit key. I'd put my money on the prior, though.
If you'd like to take your provided key in hex and use that instead, you just need to convert from hex to base64.
I expect then that your key would look like this:
XdNL4MnDRIM8keINJHw7KYg0CgNMlxnHwpHsL3gfgTM
You may need to make further adjustments to the gist you have to ensure it knows you are using a 256-bit key now.

How does differ openssl signing and encrypting programmatically

There is this question on SO:
What is the difference between encrypting and signing in asymmetric encryption?
My question is not a duplicate. I am asking if there is difference between two programmatically.
I have an openssl C++ API to sign and verify a message. Let say two functions:
sign
verify
Let say two sides who interchange messages are A and B.
Currenlty sign function uses A_privateKey, and verify function uses B_publicKey.
Now, I want to encrypt some part of the message.
So, could I do it just using sign function with B_publicKey?
Or the algorithm to encrypt is totally different and I need to implement a new function?
Or with some modification in sign function (removing generating hash, for ex) does it just work?
Now, I want to encrypt some part of the message.
So, could I do it just using sign function with B_publicKey?
The output of the sign function is an encrypted hash of the original message. If "A" were to tranmit the output of sign as you describe, the only thing B could do is decrypt it back to the hash of the original message. He wouldn't have the actual message.
Because assymetric encryption can be a very computationally expensive operation that doesn't scale well for long messages, the standard pattern is this:
Alice generates a message she wants to send to Bob.
Alice generates a symmetric key first
Alice encrypts the message with this symmetric key.
Alice encrypts the symmetric key with Bob's public key
Alice transmits the encrypted message and encrypted key to Bob.
Then Bob does this:
Bob receives both the message that was symmetrically encrypted and
the assymetrically encrypted key.
Bob decrypts the symmetric key with his public key
Bob uses the symmetric key to decrypt the encrypted message
There's probably a ton of other security principals missing as well, but the above is the general idea.

pbkdf2 sha512 password hash size

I'm a total newbie to flask let alone cryptography. I'm currently following Miguel Grinberg's flask tutorial. I'm trying to store a pbkdf2:sha512 hashed password with salt length 64 but I can't find the appropriate length to store it in the Database is it db.string(128) or 512.
Refer following pbkdf2-sha512 digest,
$pbkdf2-sha512$10001$0dr7v7eWUmptrfW.9z6HkA$w9j9AMVmKAP17OosCqDxDv2hjsvzlLpF8Rra8I7p/b5746rghZ8WrgEjDpvXG5hLz1UeNLzgFa81Drbx2b7.hg
OR
$pbkdf2.sha512.10000.4483972AD2C52E1F590B3E2260795FDA9CA0B07B96FF492814CA9775F08C4B59CD1707F10B269E09B61B1E2D11729BCA8D62B7827B25B093EC58C4C1EAC23137.DF4FCB5DD91340D6D31E33423E4210AD47C7A4DF9FA16F401663BF288C20BF973530866178FE6D134256E4DBEFBD984B652332EED3ACAED834FEA7B73CAE851D
which is ideally less than 256 character. But sometimes it will go above 256 characters also. So you should use db.string(512).

what is the encryption algorithm used by zip files?

I just want to know the exact formula (or algorithm) used for generating the pseudo random values used in encrypting the zip file. I am trying to create a password hacker(for zip files) and I also require to know how to verify if the random password generated by my program is correct. I have tried searching for an answer to this in Google but I could't find a direct solution.
I am trying to program this zip hacker in c++.
note: by formula (or algorithm) I meant: key derivation function.
I just want the necessary information as quick as possible, that's why I posted it here!
Different versions of zip-files do it differently, but basically you have an encryption-header specifying what encryption is used according to the zip-file specification.
For example, the strong encryption header looks like below and specifies the encryption algorithm in the AlgID-field.
4.5.12 -Strong Encryption Header (0x0017):
Value Size Description
----- ---- -----------
0x0017 2 bytes Tag for this "extra" block type
TSize 2 bytes Size of data that follows
Format 2 bytes Format definition for this record
AlgID 2 bytes Encryption algorithm identifier
Bitlen 2 bytes Bit length of encryption key
Flags 2 bytes Processing flags
CertData TSize-8 Certificate decryption extra field data
(refer to the explanation for CertData
in the section describing the
Certificate Processing Method under
the Strong Encryption Specification)
7-zip uses AES-256 encrpytion for 7z/zip archives.(see here)
7-Zip also supports encryption with AES-256 algorithm. This algorithm uses cipher key with length of 256 bits. To create that key 7-Zip uses derivation function based on SHA-256 hash algorithm. A key derivation function produces a derived key from text password defined by user. For increasing the cost of exhaustive search for passwords 7-Zip uses big number of iterations to produce cipher key from text password.
Also, keep in mind that Brute force attacks are a waste of time. I won't go into details why, I will instead direct you to Jeff Atwood's blog, he has an excellent post.