decrypting large file with rsa - encryption

I got a 15KB encrypted file (containing a long base64 string) , and a rsa private key file. I have to decrypt this file using the private key, but I am receiving an error while trying to do so with openssl.
This is the command I tried:
openssl rsautl -decrypt -inkey ./id_rsa -in encrypted_file.enc -out output.bin
The error I'm receiving is as follows:
RSA operation error 140360486789312:error:0406506C:rsa
routines:rsa_ossl_private_decrypt:data greater than mod
len:../crypto/rsa/rsa_ossl.c:391:
I would appreciate to get help how to do it right.
Thanks in advance.

RSA is not designed to encrypt (large) data, use symmetric encryption such as AES to encrypt data.
If you really need asymmetric encryption, that is separate encryption and decryption keys, use hybrid encryption. Hybrid encryption creates a Ranson symmetric key, encrypts the data with symmetric encryption, encrypts that symmetric key with asymmetric encryption and packaged the two together.
The size of the data that can be encrypted is less than the key size minus padding. To RSA encrypt a 15KB file would require an RSA key > 17,000 bits and that is currently unreasonable. Also asymmetric encryption (RSA) is orders of magnitude slower than symmetric encryption (AES).
But one question: do you really need asymmetric encryption, would symmetric encryption suffice for your needs?

Related

How could I encrypt and decrypt a message with a single key?

I have implemented Diffie–Hellman and I'm looking for a way to encrypt and decrypt messages with that key.
Diffie–Hellman key exchange is a protocol to enable both sides to agree on a key.
You can use this key for any symmetric encryption algorithm. AES is the current standard.
AES accepts 128,192, and 256 bits size keys. When you agreed on a key, make sure that your protocol cut the keys for appropriate sizes for the symmetric encryption algorithm.

Is ECIES a public encryption algorithm?

I've implemented RSA encryption algorithm to encrypt the symmetric key used in data encryption, but the key size and the ciphertext size of RSA created a memory issue, so I searched other methods of public key cryptography for the solution. I found elliptic curve integrated encryption scheme (ECIES) and understand the theory behind it, however, I am a bit unclear that how this method be used as public/asymmetric encryption algorithm. The method computes the symmetric encryption with the key derived from the shared secret for both encryption and decryption (using the same key).
So how could it be taken as an asymmetric encryption algorithm?
Or Is there any method to implement it as asymmetric encryption?
Meta: this isn't really a programming or development question or problem. It probably belongs on crypto.SX; you might ask for migration.
To be exact, ECIES is a hybrid public-key encryption scheme, but so are most others. For example RSA is commonly used, just as you said, to encrypt a working (per-message) symmetric key, not to directly encrypt data.
Paraphrasing the wikipedia description:
(Usually in advance) Bob generates a (static) keypair and publishes the publickey authentically (for example using a certificate)
2-5. Alice generates an ephemeral keypair, derives the shared DEK, and encrypts the data, and sends it with her ephemeral publickey
(edit) and destroys the ephemeral privatekey
Bob uses his privatekey to derive the DEK and decrypts the data
ADDED, and expanded below, per comments: Yes the DEK is the same at both ends (notice I used 'the' meaning one and not several) and that's why this scheme works; and the part of ECIES that uses DEK for data encryption and decryption is symmetric, but all the other operations (which securely create the ephemeral shared DEK) are not.
It is vital no one besides Alice (or Bob) learns her ephemeral privatekey; if they do they can decrypt. But she doesn't need to explicitly keep it secret because she destroys it immediately after using it to send a message; that's what ephemeral means.
Let's see:
the recipient's publickey is public and anyone can encrypt
the recipient has the (static) privatekey and can decrypt
nobody else has Bob's (static) privatekey or Alice's ephemeral privatekey, and nobody else can decrypt
the recipient needs only one keypair; if there are multiple senders they can all use the same publickey but can't decrypt each other's traffic, and don't need to get the publickey secretly; for a thousand or a million senders this costs the same as or very little more than one sender
Consider the properties of a standard/traditional symmetric scheme instead:
the two parties must have a key (only one, not a pair) shared in advance; both must keep it secret and not share with anybody else
this typically requires the parties meet in advance, or use a physically secure means such as a courier to carry the key from one to the other or perhaps from a central authority to both
each key can only be used by one pair of parties; for multiple senders, Bob must have and manage that many different keys, and each sender (Alice, Abby, Anne, etc) must have a different key. Each sender must separately meet Bob, or they must each have a separate courier (or two), before they communicate with him. For a thousand or a million senders this becomes immensely costly
ECIES has none of these properties of a conventional or symmetric system, and all of the properties of a publickey or asymmetric system above, although it does also use some symmetric operations along with its asymmetric operations.
And that's why it sounds like (hybrid) public-key encryption to me!
#dave_thompson_085 has explained the concept well. However, I'd like to add an example to make it clear.
Eg:
Alice generates Public "qA" and private key "dA".
Alice sends over her public key to Bob.
Using this public key, Bob generates a random pair of symmetric keys (R and S).
Bob encrypts the message with key "S" and sends over this ciphertext along with key "R" over to Alice.
With this "R" key, Alice can multiply her private key "dA" and generate the symmetric key "S" to decrypt the ciphertext.
So the message is encrypted using a symmetric key, but over the network it is asymmetric as only the public key is exchanged over the network which is used to generate the symmetric key for the receiver and the private key is used to generate the same symmetric key on the sender's side.

Is there any way to run aes-128-cbc encryption in openssl without iv?

I am trying to encrypt a text file with opensslusing aes-128-cbc encryption and I was wondering if there was a way I could encrypt it only using the key and not the iv?
Everytime I try to run:
openssl enc -aes-128-cbc -e -in dummy_file.txt -out dummy.aes-128-cbc.bin -K 00112233445566778889aabbccddeeff
I get the error saying iv undefined and the encrypted file it generates is empty and it is not even a binary file.
No, that's not possible, CBC requires an IV. You can however set the IV to all zeros. As the IV is XOR'ed with the first block of plaintext before encryption, this comes down to having no IV at all: you would directly encrypt the first block of plaintext with the block cipher.
Note that creating multiple ciphertext with the same key and IV will not result in a secure cipher. For CBC it is required to have a random (or at least unpredictable) IV. Otherwise an attacker can at least see which plaintext start with identical blocks of data.
The IV always consists of 16 bytes for AES, which comes down to 32 hexadecimal zeros, of course for the -iv command line parameter of openssl.

openssl smime: aes vs rsa - which one encrypts?

When I want to encrypt large files, I have found the following command:
openssl smime -encrypt -binary -aes-256-cbc \
-in large_file.img -out large_file.img.dat \
-outform DER \
public-rsa2048.pem
The private/public keys have been created like this:
openssl req -x509 -nodes -newkey rsa:2048 \
-keyout private-rsa2048.pem -out public-rsa2048.pem
So I am using aes-256-cbs as well as an rsa-key.
Which one is now responsible for the encrpytion?
Which one does impact the performance and how?
If I increase/lower the public key (rsa512 vs rsa4096), does this impact the performance?
If I choose a different aes algorithm, does this impact the performance as well?
Could someone bring some light into this matter please?
Are there any other methods to encrypt large files?
Using the openssl smime command to encrypt data encrypts it in such a way that it can be received and decrypted by a recipient using email. This means that it uses certificates representing various entities (sender, recipient) and containing keys uniquely associated with those entities to both sign, encrypt, decrypt, and verify signatures on the contained data.
As Artjom pointed out in their comment, a hybrid cryptosystem is used. This means a combination of symmetric and asymmetric encryption algorithms are used, as each has benefits and drawbacks. Symmetric encryption (such as AES) is extremely fast in comparison to asymmetric encryption (such as RSA). However, AES/CBC provides only confidentiality, not integrity, authentication, or non-repudiation. Asymmetric encryption can provide integrity, authentication, and non-repudiation. Asymmetric encryption also has fairly low limits for the amount of data it can encrypt (for example, an RSA-4096 bit key can encrypt at most 446 bytes at once). By combining both methods, we can exercise each for their strengths and mitigate the weaknesses of the other.
In this case, let our message be M. An AES/CBC key Kaes of length 256 bits is generated and used to encrypt the raw data such that the cipher text C is C = E(Kaes, M). The recipient's public key Krpub is then used to encrypt Kaes as C' = E(Krpub, Kaes). The cost of encrypting this small amount of data is relatively low, even though we are using an expensive operation.
Note prior to encrypting the ephemeral session key, it is likely signed using the sender's private key Kspriv unless digital signing is disabled. I am not 100% certain with S/MIME, but this is how PGP works, as when sending to multiple recipients, it would be much more expensive to encrypt the session key with n recipient's public keys and then sign each encrypted key with the sender's private key O(2n) vs. O(n+1) (not really Big-O notation, but effective for communicating the point). The signature of the session key is the same regardless of recipient because it depends only on the sender's private key.
Now all that is left is to concatenate the encrypted session key C' and the cipher text C and transmit them to the recipient. In a real S/MIME message, the identifying information about the sender's public key is transmitted as well in order to facilitate signature verification. The recipient parses the complete encrypted message, decrypts the session key using the recipient's private key Krpriv and then uses the session key Kaes to decrypt the cipher text C.
However, it seems like all of this may be overkill for your situation. If you do not need to integrate with an email communication system and are simply trying to encrypt large files for storage, openssl also offers a simple enc command. You can use it as follows:
Password-based encryption:
$ openssl enc -aes-256-cbc -in large_plain_file.dmg -out large_encrypted_file.enc -k thisIsABadPassword
-k allows you to enter a password on the command line from which the key will be derived. OpenSSL uses a deterministic key derivation function (KDF) (effectively key, iv = MD5(password||salt)). You can run this command with -p on the end to get the key, salt, and IV printed to the console. The IV is deterministically derived from the password and salt. A KDF like PBKDF2 is recommended but the library function in OpenSSL does not expose it to the command-line tool for some reason.
Warning you can run this and specify -nosalt to skip the salt generation, but this is not recommended as it makes an already extremely weak KDF even weaker.
Keyed encryption:
$ openssl enc -aes-256-cbc -in large_plain_file.dmg -out large_encrypted_file.enc K 0123456789ABCDEFFEDCBA98765432100123456789ABCDEFFEDCBA9876543210 -IV 0123456789ABCDEFFEDCBA9876543210
Running with the actual key and IV provided. The key is 32 bytes (256 bits) and the IV is 16 bytes (the size of one AES block).
To decrypt the data, run the command with the -d flag:
$openssl enc -aes-256-cbc -d -in large_encrypted_file.dmg -out large_decrypted_file.enc
This is going to be simpler for you (no certificates/key pairs needed) and faster (no RSA encryption).
Something to keep in mind for all of this is that the password/key will be kept in terminal history if you provide it in the command invocation. Running without -k or -K will prompt the password to be entered in a secure prompt. Or use -pass to read from an environment variable, file, or file descriptor.
Update to address original questions explicitly:
The AES key is responsible for encrypting the data. The RSA key is used to encrypt the AES key.
Both impact the performance. The AES key is encrypting much more data, but is much faster than RSA encryption.
Yes, changing the size of the RSA key impacts performance, (higher key sizes are slower), but for a large file this is unlikely to be the limiting factor on performance.
Yes, changing the AES mode of operation may have a substantial impact on performance. AES/CBC, AES/OFB, and AES/CFB are similar in that they are serial operations (depending on the result of one block operation to proceed to the next), but AES/CTR operates as a stream cipher and can be parallelized to provide both encryption and decryption.
See answer above.

Same RSA keys, same message, different encrypts [duplicate]

This question already has answers here:
Why does RSA encrypted text give me different results for the same text
(2 answers)
Closed 5 years ago.
I generate private/public keys, and a small text file,
openssl genrsa -out priv.pem
openssl rsa -out pub.pem -in priv.pem -pubout
echo "A" > plain.txt
When you encrypt the text file with the public key twice, as so,
openssl rsautl -encrypt -pubin -inkey pub.pem -in plain.txt -out cipher.txt
you will see that the two cipher.txt differ. This is what I do not understand.
When you encrypt the text file with the public key twice ... you will see that the two cipher.txt differ. This is what I do not understand.
This is called probabilistic encryption (versus deterministic encryption). Its that way by design so that the same message encrypted twice does not produce the same cipher text. Its due to the masking function and padding functions used by RSA.
If encryption produced the same cipher text, then your adversary could gain information. For example, if your adversary sees a message he does not understand but observers your army attacks his army the next morning, he might guess that the message was "Attack at dawn". If he sees that same encrypted message again, he's probably going to be ready for an attack at dawn the next day.
The folks on the crypto stack exchange might be able to help you further if you want the details of MGFs, OAEP and the like. Also, Dr. Steve Bellovin has a very approachable introduction to cryptography at An Introduction to Cryptography.

Resources