Encryption & Decryption AES-256-CFB in Python - python-3.x

I have aes-256-cfb decryption code in ruby as follows.
data_cipher = OpenSSL::Cipher::Cipher.new "aes-256-cfb".freeze
data_cipher.decrypt
data_cipher.key = encryption_key
data_cipher.update(decode64(str)) << data_cipher.final
I need the python equivalent of this above code. My problem here is, where ever i found python logic for aes-256-cfb it always involved Initialization vector(IV). But in the above Ruby logic, iv is not set.
I tried with Random values of iv, but that is not giving me the same result as ruby code.
Please advise.

For AES-256-CFB there is always a iv needed for encryption. If no iv is given, most likely it will be just zero (which means 16 0x00 bytes, as the iv is equal to the blocksize, which is 128bit). Another option would be that the iv is randomly generated at encryption time and is encapsulated in the message. That would mean, that the first 16 byte of the message are the iv. If you don't know how the encryption algorith works, you will probably need to try this out.
However, since the iv is only used to decrypt the first block in CFB mode, if you have a long enough message, the decryption will work just fine even if the iv is wrong (except for the first 128 bit of the message).
Below is a code sample, how decryption works in python. You need to know the iv before encryption. In the sample below I initialized it with zero bytes.
Note that this code only handles decryption of the raw message bytes. You will need to care about the encoding yourself.
from Crypto import Random
from Crypto.Cipher import AES
def decrypt(key, enc):
iv = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
cipher = AES.new(key, AES.MODE_CFB, iv)
return cipher.decrypt(enc)
More info here (note that this thread is using CBC mode, which is a litte different): Encrypt & Decrypt using PyCrypto AES 256

Related

How does an IV work and what would be the best way to store it?

I want to encrypt and decrypt strings. I'm using Nodejs crypto for this. I've read that when encrypting and decrypting it's highly recommended to use an IV. I want to store the encrypted data inside a MySQL database and decrypt it later when needed. I understand that I need the IV also for the decryption process. But what exactly is an IV and how should I store it? I read something about that an IV does not to be kept secret. Does this mean I can store it right next to the encrypted data it belongs to?
it's highly recommended to use an IV
No, it's required or you'll not get a fully secure ciphertext in most circumstances. At the very minimum, not supplying an IV for the same key and plaintext message will result in identical ciphertext, which will leak information to an adversary. In other words: encryption would be deterministic, and that's not a property that you want from a cipher. For CTR and GCM mode you may well leak all of the plaintext message though...
But what exactly is an IV ... ?
An IV just consists of binary bits. It's size and contents depend on the mode of operation (CBC/CTR/GCM). Generally it needs either to be a nonce or randomized.
CBC mode requires a randomized IV of 16 bytes; generally a cryptographically secure random number generator is used for that.
CTR mode commonly specifies both a nonce and the initial counter value within the IV of 16 bytes. So you already need to put the nonce in the left hand bytes (lowest index). This nonce may be randomized, but then it should be large enough (e.g. 12 bytes) to avoid the birthday problem.
GCM mode requires just a nonce of 12 bytes.
and how should I store it
Anyway you can store the bytes, as long as they can be retrieved or regenerated during decryption. If you need text you may need to encode it using base 64 or hexadecimals (this goes for the ciphertext as well, of course).
I read something about that an IV does not to be kept secret.
That's correct.
Does this mean I can store it right next to the encrypted data it belongs to?
Correct, quite often the IV is simply prefixed to the ciphertext; if you know the block cipher and mode of operation then the size is predetermined after all.

When deciphering with RC4, what does it mean to skip bytes?

I have the binary data that I need to decipher, the algorithm (RC4) and the key. However, to decipher the data, one instruction I got is that "the length of the key initially gets skipped" or that "len bytes are skipped initially".
What does this mean exactly? Does it mean that if my key is 10 bytes long, that I need to pass in the binary data without the first 10 bytes to the decipher and then concatenate the first 10 bytes with the deciphered bytes?
const decipher = crypto.createDecipheriv('RC4', 'mysuperkey', null);
const buffer = decipher.update(data.slice('mysuperkey'.length));
decipher.final();
This does not work, so I might not understand the instruction.
RC4 is insecure for the first bits, so often you are instructed to skip over some initial bytes of the key stream. The way a stream cipher works is that it creates a stream of pseudo random data that depends on the key. That stream is XOR'ed with the plaintext to create the ciphertext, and with the ciphertext to create the plaintext.
To skip a number of bytes of the key stream you can simply encrypt / decrypt some (zero valued) bytes and throw away the results. This goes both for encryption and decryption. If the API has a specific skip method then you should of course use that, but I don't think it is present in CryptoJS.

What is the equivalent cipher to bouncycastle's PaddedBufferedBlockCipher with AESEngine and PKCS7 padding?

I want to decrypt AES-256 encrypted string using nodejs. I am using crypto module for that.
The string is encrypted using Bouncy castle java library. In Java the cipher is intialsed using:
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new AESEngine(), new PKCS7Padding());
crypto module of nodejs uses openssl's list of ciphers for intialising it, like:
var decipher = crypto.createDecipher('aes-256-cbc',key);
Which algorithm should I use?
Here is the list of algorithms to choose from:
-bash-4.1$ openssl list-cipher-algorithms|grep AES-256
AES-256-CBC
AES-256-CFB
AES-256-CFB1
AES-256-CFB8
AES-256-CTR
AES-256-ECB
AES-256-OFB
AES-256-XTS
AES256 => AES-256-CBC
aes256 => AES-256-CBC
If you encrypt something with a block cipher, you need
the block cipher which can take a single block of input and mangle it into a single block of output (for AES the block size is 16 bytes),
the mode of operation which enables you to encrypt more than one block in a structured fashion
the padding which enables you to encrypt something that is not exactly as long as a multiple of the block size.
The PaddedBufferedBlockCipher that you've shown only has two of them. The mode of operation is implied to be ECB mode, because it simply consists of applying the block cipher to each block separately.
You'll get the same behavior in node.js with:
var decipher = crypto.createDecipheriv('aes-xxx-ecb', key, '');
Exchange the xxx for the size of your key in bits. Valid sizes are 128 bit, 192 bit and 256 bit. Everything else will not work. Also, make sure that you get the encoding of your key right.
In case you're wondering why createDecipheriv is used here instead of createDecipher, I suggest that you carefully compare the documentation to both of those functions. createDecipher expects a password and not a key.
Other considerations:
Never use ECB mode. It's deterministic and therefore not semantically secure. You should at the very least use a randomized mode like CBC or CTR. It is better to authenticate your ciphertexts so that attacks like a padding oracle attack are not possible. This can be done with authenticated modes like GCM or EAX, or with an encrypt-then-MAC scheme.
Decrypt the data with AES-256-ECB (I don't see any CBC or other modes.).
Call decipher.setAutoPadding(true) for using PKCS padding.

AES-256 encryption workflow in scala with bouncy castle: salt and IV usage and transfer/storage

I'm trying to implement secure encryption of the files to be sent over insecure channel or stored in an insecure place. I use bouncy castle framework, my code is written in scala. I decided to use aes-256 (to be more specific - Rinjael with 256 bit block size, here is why). And it seems like I can use Rinjael with any (128|160|192|256) block length.
I cannot understand the whole process overview correctly. Here is one of good answers, in this question there is some useful code specific to bouncy castle. But both leaving some questions unanswered for me (questions below).
So this is how I understand the workflow:
For creating a block cipher instance I have to get an instance of padded block cipher with some output feedback:
// create an instance of the engine
val engine = new RijndaelEngine(bitLength)
// wrap engine with some feedback-blocking cipher mode engine
val ofb = new OFBBlockCipher(engine , bitLength)
// wrap this with some padded-blocking cipher mode
val cipher = new PaddedBufferedBlockCipher(ofb, new PKCS7Padding())
Now I have to run init() on the cipher engine
2.1. first generate a key, to do this the best solution suggested here was to use Scrypt to derive a secret from password instead of using PBKDF2-HMAC-xxx. In russian wikipedia article on Scrypt it is said that the recommended parameters for Scrypt are as follows: N = 16384, r = 8, p = 1
So I'we wrirtten this code to generate the password:
SCrypt.generate(password.getBytes(encoding), salt, 16384, 8, 1, bitLength / 8)
2.2. This leads to that I need a salt. Salt should be an array of random bytes. Most answers here use 8 bytes. So I do
// helper method to get a bunch of random bytes
def getRandomBytes(size: Int) = {
val bytes = Array.ofDim[Byte](size)
val rnd = new SecureRandom()
rnd.nextBytes(bytes)
bytes
}
// generate salt
val salt = getRandomBytes(8)
2.3. For cipher to initialize we need an initialization vector (please take a look at my question (2) below).
val iv = getRandomBytes(bitLength / 8)
2.4. Now we are ready to initialize the cipher.
cipher.init(mode, params(password, salt, iv, bitLength))
Questions:
What should be the size of salt? Why do most respondents here use 8 bytes, not more?
What should be the size of IV? Is it correct that it should be the same size as cipher block size? Is it preferred to be fetched from cipher like here: cipher.getParameters().getParameterSpec(IvParameterSpec.class).getIV(); or to be just random as i did?
Is it correct that I need both the salt and IV or I can use just one of these? For example use random IV as a salt.
And the main question: I have to pass salt and IV to the other side or else it would be not possible to decrypt the message. I need to somehow pass both over unencrypted channel. Is it secure to just add both before an encrypted message (as a header)?
Thanks in advance!
I would go for 16 bytes salt length as suggested
IV should be size of block size of cipher and should be random
Yes you need both salt and IV because salt is used to generate key from password and IV is used to initialize block cipher
Salt and IV are designed to be public. You can send them or store unencrypted, but you do not use any authentication mechanism so anyone can change IV or Salt during transport and you would not be able to detect it and decryption will get you something different. To prevent that you should use some AEAD mode and include IV and salt in authentication.
Is it secure? Sure, they will still need to guess the passphrase. Is it as secure? No, because you're giving the attacker information that they need to simplify the decryption process. If the only way that you can get the salt/password to the other side is via an unencrypted channel then something is better than nothing I suppose, but why can't you exchange this information using PKI/SSL?

Can you 'convert' ciphertext encrypted in CBC mode to ECB mode with known IV?

In CBC mode, C2 = Ek(C1 ⊕ P2)
C2 = 2nd block of ciphertext
P2 = 2nd block of plaintext
Ek = encryption function
If IV is known (let's say it's set to 0), is there anyway to find the ciphertext block such that C2 = Ek(P2) ?
If the message is only 1 block in size and the IV is null, then both ECB and CBC modes will produce an equivalent cipher text. However, the short answer to your question is NO. In most cases (like WEP and WPA) the IV is known to the attacker and this does not compromise the system. However, make sure that the IV is random when using CBC mode.
In Cipher Block Chaining mode (CBC), each plain text block is xor'ed with the previous cipher text block in the sequence. Thus you cannot decrypt the message in its entirety without following the "chain" or series of decryption routines. Its kind of like a one-time-pad meets a block cipher. The algorithm isn't that complex and here is a graphical representation of the two. Notice that they are nearly identical except CBC mode adds XOR operation for each block.
The simple answer is that if what you ask for was possible in general then CBC would then be equivalent to ECB anyway - there would be no security gained by CBC over ECB.
There is, however, an information leak in CBC. If you happen to observe two identical ciphertexts in CBC messages that were encrypted with the same key, Cn = Cm, then you can calculate Pn ⊕ Pm (it is equal to Cn-1 ⊕ Cm-1). Two identical ciphertexts are only likely in two cases: the first is that the sender re-used an IV, and the second is that you have observed a very large amount of traffic encrypted with the same key (for a 128 bit block cipher, on the order of 16 million TB; for a 64 bit block cipher, on the order of 4 GB).

Resources