RSA encryption difficulty - encryption

I'm writing a python script to encrypt/decrypt strings with RSA. I have no problems with the algorithm itself, but I don't understand how to use it correctly.
I mean, there is no point in encrypting every each symbol in a string separately. Because same symbols will give us same ciphers (like Caesar cipher). So I think I should divide the whole message into blocks of same length.
But it makes it difficult to decrypt the message. Because after you encrypt the blocks, the length of each block could change. So when decrypting, you don't know where a certaing blocks starts and where it ends.
For example, when I encrypt "stronger" with RSA I get:
5716225862
I divided the original message into 4 blocks of 4 symbols. But after encrypting I get a message of 10 symbols. And that's the problem.
Hope, you understand what I mean. Sorry for my bad English.

Simply said, RSA is not for directly encrypting plain text, it is used for encrypting a symmetric key (AES, for instance), and this is with this symmetric key that you will encrypt (and further decrypt) your plain text.
Since the plain text may have any size, it is encrypted using AES with a stream cipher (for instance AES-256-GCM) or a block cipher (for instance AES-256-CBC).
With AES, same symbols will not give same ciphers, since you have to choose a new random IV (initialization vector) each time you encrypt your plain text.
So, you need to use a 2-steps encryption scheme: use RSA to encrypt a symmetric key, and use this symmetric key to encrypt your plain text.

Related

Encrypting Text as well as Integers

Hi i have created an RSA encryption using Java that so far only encrypts and decrypts BigIntegers and would like to make it so that it can also do the same for other characters, i have a feeling that i would have to convert everything into Ascii (if this is even possible) to then encrypt but no idea how.
i would have to convert everything into Ascii
consider encryption as converting a byte array to a different byte array (even BigInt is represented as a byte array)
Still I see several issues:
You are implementing your own textbook RSA (no padding, no mitigation for side-channel attacks) and this approach is really really not secure. It's ok to do it for learning purposes (even I'd object) , but not for any real life secure encryption.
RSA is secure (when used properly) to encrypt a fixed block of data. If you want to use RSA to encrypt data of any length, you may use hybrid encryption (use symmetric encryption with a random key to encrypt data and RSA to encrypt the key)
you may have a look at my blog for that
https://gusto77.wordpress.com/2017/10/30/encryption-reference-project/

Storing IV when using AES asymmetric encryption and decryption

I'm looking at an C# AES asymmetric encryption and decryption example here and not sure if i should store the IV in a safe place (also encrypted??). Or i can just attach it to the encrypted text for using later when i with to decrypt. From a short reading about AES it seems it's not needed at all for decryption but i'm not sure i got it right and also the aes.CreateDecryptor(keyBytes, iv) need it as parameter.
I use a single key for all encryptions.
It's fairly standard to transmit the encrypted data as IV.Concat(cipherText). It's also fairly standard to put the IV off to the side, like in PKCS#5.
The IV-on-the-side approach matches more closely with how .NET wants to process the data, since it's somewhat annoying to slice off the IV to pass it separately to the IV parameter (or property), and then to have a more complicated slicing operation with the ciphertext (or recovered plaintext).
But the IV is usually transmitted in the clear either way.
So, glue it together, or make it a separate column... whatever fits your program and structure better.
Answer: IV is necessary for decryption as long as the content has been encrypted with it. You don't need to encrypt or hide the IV. It may be public.
--
The purpose of the IV is to be combined to the key that you are using, so it's like you are encrypting every "block of data" with a different "final key" and then it guarantees that the cipher data (the encrypted one) will always be different along the encryption (and decryption) process.
This is a very good illustration of what happens IF YOU DON'T use IV.
Basically, the encryption process is done by encrypting the input data in blocks. So during the encryption of this example, all the parts of the image that have the same color (let's say the white background) will output the same "cipher data" if you use always the same key, then a pattern can still be found and then you didn't hide the image as desired.
So combining a different extra data (the IV) to the key for each block is like you are using a different "final key" for each block, then you solve your problem.

Why the time RSA encryption and decryption depends on the key size and not the input length?

I read some white paper about RSA encryption. I find this statement. but I can't understood why?
Statment is The time for RSA encryption and Decryption depends on the key size, but does not depend on the size and content of input data, if this statment right meaningly wehen encrypt 1000 byte , 10000 byte same time for encrypt and decrypt?
The time is always the same because the input length is always the same.
The plain text is padded to the size of the RSA modulus. If the plain text is too long, you cannot encrypt it with RSA. Of course, you can split your plain text up and encrypt each chunk with an independent RSA operation, but this isn't how the algorithm was intended to be used.
RSA encryption is best suited as a key transport algorithm. You choose a symmetric key, and use an RSA public key to encrypt it. The symmetric key can be used for encrypting a lot of data with some algorithm like AES. This is much, much faster than using public key cryptography to encrypt and decrypt bulk data.

How does the receiver of a cipher text know the IV used for encryption?

If a random IV is used in encrypting plain text, how does the receiver of the cipher text know what the IV is in order to decrypt it?
This is a follow-up question to a response to the previous stackoverflow question on IVs here.
The IV allows for plaintext to be encrypted such that the encrypted text is harder to decrypt for an attacker. Each bit of IV you use will double the possibilities of encrypted text from a given plain text.
The point is that the attacker doesn't know what the IV is and therefore must compute every possible IV for a given plain text to find the matching cipher text. In this way, the IV acts like a password salt. Most commonly, an IV is used with a chaining cipher (either a stream or block cipher). ...
So, if you have a random IV used to encrypt the plain text, how do you decrypt it? Simple. Pass the IV (in plain text) along with your encrypted text.
Wait. You just said the IV is randomly generated. Then why pass it as plain text along with the encrypted text?
The answer that you quote is wrong. So don't worry if it does not make sense to you.
IVs don't make breaking a ciphertext harder. IVs are ususlly just prepended to the ciphertext and hence known to a potential attacker.
The main reason to use IVs is to randomize the ciphertext. If you encrypt the same plaintext twice with the same key, but different IVs then the ciphertext should be different. Ideally an attacker should not be able to tell if two ciphertexts correspond to the same plaintext or different plaintexts of the same length. More formally, IVs are used so that the encryption has ciphertext indistinguishability.
If a random IV is used in encrypting
plain text, how does the receiver of
the cipher text know what the IV is in
order to decrypt it?
The Wikipedia article on Initialization vectors provides several examples of ways to tell the receiver what the IV is.
Wait. You just said the IV is randomly
generated. Then why pass it as plain
text along with the encrypted text?
If the IV is randomly generated (at encrypt time), then only the sender knows what it is. In order to decrypt the message, the receiver needs to know the IV too.

Should I use an initialization vector (IV) along with my encryption?

Is it recommended that I use an initialization vector to encrypt/decrypt my data? Will it make things more secure? Is it one of those things that need to be evaluated on a case by case basis?
To put this into actual context, the Win32 Cryptography function, CryptSetKeyParam allows for the setting of an initialization vector on a key prior to encrypting/decrypting. Other API's also allow for this.
What is generally recommended and why?
An IV is essential when the same key might ever be used to encrypt more than one message.
The reason is because, under most encryption modes, two messages encrypted with the same key can be analyzed together. In a simple stream cipher, for instance, XORing two ciphertexts encrypted with the same key results in the XOR of the two messages, from which the plaintext can be easily extracted using traditional cryptanalysis techniques.
A weak IV is part of what made WEP breakable.
An IV basically mixes some unique, non-secret data into the key to prevent the same key ever being used twice.
In most cases you should use IV. Since IV is generated randomly each time, if you encrypt same data twice, encrypted messages are going to be different and it will be impossible for the observer to say if this two messages are the same.
Take a good look at a picture (see below) of CBC mode. You'll quickly realize that an attacker knowing the IV is like the attacker knowing a previous block of ciphertext (and yes they already know plenty of that).
Here's what I say: most of the "problems" with IV=0 are general problems with block encryption modes when you don't ensure data integrity. You really must ensure integrity.
Here's what I do: use a strong checksum (cryptographic hash or HMAC) and prepend it to your plaintext before encrypting. There's your known first block of ciphertext: it's the IV of the same thing without the checksum, and you need the checksum for a million other reasons.
Finally: any analogy between CBC and stream ciphers is not terribly insightful IMHO.
Just look at the picture of CBC mode, I think you'll be pleasantly surprised.
Here's a picture:
http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation
link text
If the same key is used multiple times for multiple different secrets patterns could emerge in the encrypted results. The IV, that should be pseudo random and used only once with each key, is there to obfuscate the result. You should never use the same IV with the same key twice, that would defeat the purpose of it.
To not have to bother keeping track of the IV the simplest thing is to prepend, or append it, to the resulting encrypted secret. That way you don't have to think much about it. You will then always know that the first or last N bits is the IV.
When decrypting the secret you just split out the IV, and then use it together with the key to decrypt the secret.
I found the writeup of HTTP Digest Auth (RFC 2617) very helpful in understanding the use and need for IVs / nonces.
Is it one of those things that need to be evaluated on a case by case
basis?
Yes, it is. Always read up on the cipher you are using and how it expects its inputs to look. Some ciphers don't use IVs but do require salts to be secure. IVs can be of different lengths. The mode of the cipher can change what the IV is used for (if it is used at all) and, as a result, what properties it needs to be secure (random, unique, incremental?).
It is generally recommended because most people are used to using AES-256 or similar block ciphers in a mode called 'Cipher Block Chaining'. That's a good, sensible default go-to for a lot of engineering uses and it needs you to have an appropriate (non-repeating) IV. In that instance, it's not optional.
The IV allows for plaintext to be encrypted such that the encrypted text is harder to decrypt for an attacker. Each bit of IV you use will double the possibilities of encrypted text from a given plain text.
For example, let's encrypt 'hello world' using an IV one character long. The IV is randomly selected to be 'x'. The text that is then encrypted is then 'xhello world', which yeilds, say, 'asdfghjkl'. If we encrypt it again, first generate a new IV--say we get 'b' this time--and encrypt like normal (thus encrypting 'bhello world'). This time we get 'qwertyuio'.
The point is that the attacker doesn't know what the IV is and therefore must compute every possible IV for a given plain text to find the matching cipher text. In this way, the IV acts like a password salt. Most commonly, an IV is used with a chaining cipher (either a stream or block cipher). In a chaining block cipher, the result of each block of plain text is fed to the cipher algorithm to find the cipher text for the next block. In this way, each block is chained together.
So, if you have a random IV used to encrypt the plain text, how do you decrypt it? Simple. Pass the IV (in plain text) along with your encrypted text. Using our fist example above, the final cipher text would be 'xasdfghjkl' (IV + cipher text).
Yes you should use an IV, but be sure to choose it properly. Use a good random number source to make it. Don't ever use the same IV twice. And never use a constant IV.
The Wikipedia article on initialization vectors provides a general overview.

Resources