Is that a way to find out how many padded space in ciphertext? I am using Rjindaal 256 bit encryption.
Problem: On decryption, I am getting error saying "Padding is invalid and cannot be removed". I am using same Initialization vector and encryption keys for both encryption and decryption.
Related
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.
I am trying to implement a SOAP client that's supposed to receive an message (XML) with MTOM/XOP attachment. The message body and attachment are encrypted using separate keys. The encryption algorithm used is AES128-CBC. The body is base64 encoded and decrypts fine, however the attachment is binary and has odd lengths (530 bytes, 527 bytes, etc).
My question is, is it possible that the server is messing something up in encryption? Or is it possible to produce AES128 output that's not multiple of 16?
AES in CBC mode will always produce output that is a multiple of 16 bytes.
If AES is used in CTR (Counter) mode) it produces output with the same length as the input.
AES is a block cipher and works with 16-byte blocks that is 16-bytes of data at a time. For CBC mode the input and output must be a multiple of 16-bytes. CTR mode does not have this requirement.
The way around this is to add padding bytes to the input prior to encryption and remove them after decryption. This can be done automatically by specifying a padding type, generally PKCS#7 padding.
In encryption methods like RSA, we operate on an integer which represents our message. I've toyed around with converting the string to an array of bytes and working one character at a time, but that seems overly slow and the RSA algorithm is designed to work with the entire message.
How do we convert a string to a representation (integer, big integer etc) in which we can apply our cryptographic algorithm too?
In typical usage, you don't actually encrypt the entire message using RSA. Instead, you encrypt the encryption key for a symmetric block cipher (like AES) using RSA, then encrypt your stream of data using that block cipher.
Do not attempt to do this on your own! You have to be very careful with how you do the conversion, including setting up a secure padding scheme and using the block cipher correctly and in a secure mode. You might want to look using language-provided crypto libraries or a standard library like OpenSSL.
Hope this helps!
Think about how integers and strings are represented in memory. A 32-bit integer takes up four 8-bit bytes, and a 64-bit integer takes up eight bytes. A string is stored as bytes too, and in case of ASCII, each characters is represented by one byte. (UTF-8 and UTF-16 are variable length encodings, but it's still bytes.)
There is nothing to convert, because all datatypes are represented by bytes internally.
There's no reason this can't be extended to, say, 2048-bit integers for use with RSA.
My device doesn't support full 3DES (EDE). How can I emulate one using standard DES? Encryption mode is CBC.
You start by picking three independent DES keys which are not related to each other in any way.
You will want to put DES into ECB mode, not CBC mode. You also need to ensure that each encryption and decryption operation is done only on 64-bit blocks and nothing more or less. Padding schemes and the likes will cause a vulnerability in the implementation and will lead to the discovery of the block content via brute force faster than a brute force against each key.
Using the first key, encrypt your plaintext. Using the second key, decrypt that value. Using the third key, encrypt the value for your full block. It looks like this:
Encrypt(k3, Decrypt(k2, Encrypt(k1, plaintext)))
Decryption is the other way around and looks like this:
Decrypt(k1, Encrypt(k2, Decrypt(k3, ciphertext)))
When you encrypt your blocks with 3DES you then need to apply your mode of operation like CBC or CTR and apply padding if needed.
Be careful.
Block mode encryption
What you do is that you split the key of size 128 bit (16 byte) or 168 bit (24 byte) in two or three pieces respectively. So for a 16 byte key K you would have two keys Ka and Kb, and for a 24 byte key you would have Ka, Kb and Kc. DES ABC keys have an effective strength of about 112 bits, DES ABA keys have an effective strength of about 80 bits.
To encrypt a single block of 8 bytes (the block size of both DES and 3DES) you would perform the following cryptographic operation: Cn = E(Ka, D(Kb, E(Kc, Mn))) where Mn is the n'th block of the plain text message and Cn the n'th block of the cipher text. If you don't have a Kc then you may use Ka (DES ABC key vs DES ABA key).
For this you need a single block DES encrypt, which is identical to a single block encrypt in ECB mode, or a single block encrypt with CBC and an IV consisting of 8 bytes valued 00h.
CBC
So that's the block encryption sorted, now you need some kind of encryption mode and padding mode. I'll explain CBC mode encryption here, ECB should not be used for encryption non-random data.
With CBC mode encryption you XOR a vector to the plain text. The vector is normally just the output of the last DESede encrypted block. As you don't have any preceding cipher text, you need to create the first vector yourself using random data. This vector is called the initialization vector or IV. See wikipedia for a clear picture.
Padding
Block cipher modes only allow full blocks of plain text to be encrypted. So you would need some kind of padding scheme. Although there are many padding modes, PKCS#5 padding is used most of the time. You should pad the plain text like this: pad with bytes valued 0Xh, where X is the number of padding bytes required to create a full block. X should be between 1 and 8: in other words, PKCS#5 padding is always used; this makes it possible to distinquish the padding bytes from the plain text.
If you use padding in an online protocol then you need to protect against padding oracle attacks. In this case it is highly recommended to use some form of integrity checks, e.g. by adding a HMAC over the cipher text using a separate key.
3DES is just DES used three times on the plaintext:
ciphertext = E_K3(D_K2(E_K1(plaintext)))
plaintext = D_K1(E_K2(D_K3(ciphertext)))
E_Kn = Encryption with Key number n.
D_Kn = Decryption with Key number n.
So you can easily "emulate" 3DES with just DES.
In CBC mode you'll need an IV to start with and then XOR the next plaintext block with the previous ciphertext block. If your device doesn't support CBC then this too is easily "emulated".
How hard is it for a given ciphertext generated by a given (symmetric or asymmetric) encryption algorithm working on a plaintext/key pair, to find a different plaintext/key pair that yields the same cyphertext?
And how hard is it two find two plaintext/key pairs lead to the same cyphertext?
What led to this question, is another question that might turn out to have nothing to do with the above questions:
If you have a ciphertext and a key and want to decrypt it using some decryption routine, the routine usually tells you, if the key was correct. But how does it know it? Does it look for some pattern in the resulted plaintext, that indicates, that the decryption was successful? Does there exists another key results in some different plaintext, that contains the pattern and is also reported "valid" by the routine?
Follow-up question inspired by answers and comments:
If the allowed plaintext/key pairs where restricted in the on of the following (or both) way(s):
1) The plaintext starts with the KCV (Key check value) of the key.
2) The plaintext starts with a hash value of some plaintext/key combination
Would this make the collision finding infeasible? Is it even clear, that such a plaintext/key exists=
The answer to your question the way you phrased it, is that there is no collision resistance what so ever.
Symmetric case
Let's presume you got a plain text PT with a length that is a multiple of the block length of the underlying block cipher. You generate a random IV and encrypt the plain text using a key K, CBC mode and no padding.
Producing a plain text PT' and key K' that produces the same cipher text CT is easy. Simply select K' at random, decrypt CT using key K' and IV, and you get your colliding PT'.
This gets a bit more complicated if you also use padding, but it is still possible. If you use PKCS#5/7 padding, just keep generating keys until you find one such that the last octet of your decrypted text PT' is 0x01. This will take on average 128 attempts.
To make such collision finding infeasible, you have to use a message authentication code (MAC).
Asymmetric case
Something similar applies to RSA public key encryption. If you use no padding (which obviously isn't recommended and possibly not even supported by most cryptographic libraries), and use a public key (N,E) for encrypting PT into CT, simply generate a second key pair (N',E',D') such that N' > N, then PT' = CT^D' (mod N) will encrypt into CT under (N',E').
If you are using PKCS#1 v1.5 padding for your RSA encryption, the most significant octet after the RSA private key operation has to be 0x02, which it will be with a probability of approximately one in 256. Furthermore the first 0x00 valued octet has to occur no sooner than at index 9, which will happen with a high probability (approximately 0,97). Hence, on average you will have to generate on average some 264 random RSA key pairs of the same bit size, before you hit one that for some plain text could have produced the same cipher text.
If your are using RSA-OAEP padding, the private key decryption is however guaranteed to fail unless the cipher text was generated using the the corresponding public key.
If you're encrypting some plaintext (length n), then there are 2n unique input strings, and each must result in a unique ciphertext (otherwise it wouldn't be reversible). Therefore, all possible strings of length n are valid ciphertexts. But this is true for all keys. Therefore, for any given ciphertext, there are 2k ways of obtaining it, each with a different key of length k.
Therefore, to answer your first question: very easy! Just pick an arbitrary key, and "decrypt" the ciphertext. You will get the plaintext that matches the key.
I'm not sure what you mean by "the routine usually tells you if the key was correct".
One simple way to check the validity of a key is to add a known part to the plaintext before encryption. If the decryption doesn't reproduce that, it's not the right key.
The known part should not be a constant, since that would be an instant crib. But it could be e.g. be a hash of the plaintext; if hashing the decrypted text yields the same hash value, the key is probably correct (with the exception of hash collisions).