How to make IvParameterSpec random but still decrypt - java

For Encryption in Java... the article at http://cwe.mitre.org/data/definitions/329.html states that the Initialization Vector should be different each time, but if I use a different IV to decrypt than the one I used to encrypt, I get garbage characters instead of the data I expected.
What is the proper way to encrypt on one server and decrypt on another without having to communicate the IV back and forth in between servers?
The common technique seems to be to hardcode a byte array, but supposedly that's insecure???

I believe an IV is like a salt - it's not a secret, it's just used to introduce an extra element of randomness so that the same message encrypted with the same key still comes out differently each time.
So you can transmit the IV used to encrypt as part of the encrypted value, just like you'd store the salt along with a hash for a hashed value.
Of course, I could be completely incorrect...

you have to add the information that you want to avoid, inside the encrypted data, which is an array of bytes, and then removing during the conversation.
the IvParameterSpec is based on fixed array, so you know the length of the part to add and to remove. The removed part is used to recreate the parameters you pass during the chypher initialization.
please have a look at this class I created:
https://github.com/spannozzo/tk-integration/blob/master/tk-integration-util/src/main/java/org/acme/util/AESUtil.java

Related

Is a non-random initialization vector still bad when encrypting short strings?

We encrypt with AES 256 CBC PKCS5PADDING in Java with the libraries one has to download from Oracle, with Base64 encoding of the resulting byte arrays. I have read that static common initialization vector drastically decreases the security as texts that starts with the chars will looks the same when encrypted. Is this still true for short strings (12 numeric chars)?
I have encrypted a large set and I cannot find any reoccurring substrings in the resulting encrypted strings, even when they start with the same sequence.
Example (plaintext on the left and resulting encrypted string on the right)
555555555501 -> U0Mkd0PPloB5iLBy5jM6nw==
555555555502 -> NUHWaFs62LMEeyoGA0mGoQ==
555555555503 -> X3/XJNd4TzEsMv7V0bXwqg==
Albeit separate from the question, but to preempt some suggestions: we need to be able to do look ups based on plaintext strings and to be able to decrypt. We could do both hashing and encryption, but prefer to avoid it if it does not improve security significantly as it adds complexity.
I have read that static common initialization vector are bad as one can derive the key from encrypted strings.
I'm curious: where have you read that?
With short (<=16 bytes) plaintext, a random IV effectifely works as a Salt, i.e. it causes the ciphertext to differ even if the plain text is the same. This is an important feature in a lot of applications. But you write:
We need to be able to do look ups based on plaintext strings.
So you want to build some sort of pseudonymization database? If that is a requirement for you, the feature that salt, and in your case random IV adds, is actually one that you specifically don't want. Depending on your other requirements you can probably get away with using a static IV here. But for pseudonymization in general, it is recommended to use a dedicated pseudonym. In your case the data seems to be atomic. But in the general case of, for example, address data, you want to hash the name, the zip code, the city and whatever else your pseudonym is, separately, both to allow more specific queries, and to keep access to and information flow from your data under strict control.

How to ensure the encrypted length are same as the given string

Hi is it possible to encrypt the string with the certain length that i want? for example: i want to encrypt this string BI000001 to something like hex value A3D5F2ARD3(random) fixed it at 10 length. Therefore when user enter this value A3D5F2ARD3, system will based on this value and decrypt it to get back the value BI000001 .
is it possible to do this in java?
I tried a lot of method but all encrypted length are way too long.
I am not aware of any JDK built-in Java encryption method which provides this feature. Then again, I am not an encryption expert, but I guess such a custom feature won't be built in the JDK.
Maybe this discussion is also useful: https://crypto.stackexchange.com/questions/6098/is-there-a-length-preserving-encryption-scheme
Why do you want to preserve size of the string? maybe there is another solution for your problem.
Typically you would use a block cipher such as AES to encrypt data. Block ciphers (as their name suggest) work in blocks of data of a fixed size, for example AES works in blocks of 128 bits. If a block cipher encounters input smaller than the block size it pads it, which is likely why you are seeing the ciphertext larger than the plaintext.
If you want to preserve the length then consider Format Preserving Encryption as mentioned in this question.

CRC check redundant when using encryption?

I am using AES for encryption and CRC to check data integrity and I have the impression that the CRC check is redundant in my case. I am doing the following:
Encryption:
Take the payload data and calculate CRC from it
Encrypt payload data plus CRC
Decryption:
Decrypt data
Calculate new CRC of payload data and compare it with the old CRC
I wanted to provoke a CRC check failure in my unit test but when I manipulate the payload data the decryption always throws a BadPaddingException.
My question is: If the decryption always throws this exception when data is corrupted or manipulated (will it?) isnĀ“t the CRC check redundant the way I am using it?
Assuming the incorrectly decrypted data is uniformly distributed, it will appear to be correctly PKCS5/PKCS7 padded about 1 time for every 255 incorrect passwords. This means that there is still a 1/255 chance that a correct change will occur and the item will decrypt into garbage. Therefore your check is not a waste.
If you actually want the behavior you expected, you can use "AES/CTR/NoPadding", which will not require an exact block size and will always return a decrypted byte[], whether or not the keys match.
However if an attacker can repeatedly alter the ciphertext and get you to decrypt it, (an example might be encrypted data stored in a cookie) and if they can distinguish between your behavior when the decrypted data throws an exception for bad padding and when it is simply garbage, then they can determine the plaintext via a "padding oracle attack".
You may also want to consider if a more robust fingerprint than CRC may be appropriate like SHA-256 for ensuring message integrity.
A lot of this is repeated from: AES BadPaddingException

Symmetric Encryption between .NET and Java

I am using a 3rd party platform to create a landing page, it is a business requirement that I use this particular platform.
On their page I can encrypt data and send it to my server through a request parameter when calling a resource on my site. This is done through an AES Symmetric Encryption.
I need to specify a password, salt (which must be a hex value) and an initialization vector (but be 16 characters).
Their backend is a .NET platform. I know this because if I specify an IV longer than it expects the underlying exception is:
System.Security.Cryptography.CryptographicException: Specified initialization vector (IV) does not match the block size for this algorithm.
Source: mscorlib
So for example, on their end I specify:
EncryptSymmetric("Hello World","AES","P4ssw0rD","00010203040506070809", "000102030405060708090A0B0C0D0E0F")
Where the inputs are: plain text, algorithm, pass phrase, salt, and IV respectively.
I get the value: eg/t9NIMnxmh412jTGCCeQ==
If I try and decrypt this on my end using the JCE or the BouncyCastle provider I get (same algo,pass phrase, salt & IV, with 1000 iterations): 2rrRdHwpKGRenw8HKG1dsA== which is completely different.
I have looked at many different Java examples online on how to decrypt AES. One such demo is the following: http://blogs.msdn.com/b/dotnetinterop/archive/2005/01/24/java-and-net-aes-crypto-interop.aspx
How can I decrypt a AES Symmetric Encryption that uses a pass phrase, salt and IV, which was generated by the .NET framework on a Java platform?
I don't necessarily need to be able to decrypt the contents of the encryption string if I can generate the same signature on the java side and compare (if it turns out what is really being generated here is a hash).
I'm using JDK 1.5 in production so I need to use 1.5 to do this.
As a side note, a lot of the example in Java need to specify an repetition count on the java side, but not on the .NET side. Is there a standard number of iterations I need to specify on the java side which matches the default .NET output.
It all depends on how the different parts/arguments of the encryption are used.
AES is used to encrypt bytes. So you need to convert the string to a byte array. So you need to know the encoding used to convert the string. (UTF7, UTF8, ...).
The key in AES has some fixed sizes. So you need to know, how to come from a passphrase to an AES key with the correct bitsize.
Since you provide both salt and IV, I suppose the salt is not the IV. There is no standard way to handle the Salt in .Net. As far as I remember a salt is mainly used to protect against rainbow tables and hashes. The need of a Salt in AES is unknown to me.
Maybe the passphrase is hashed (you did not provide the method for that) with the salt to get an AES key.
The IV is no secret. The easiest method is to prepend the encrypted data with the IV. Seen the length of the encrypted data, this is not the case.
I don't think your unfamiliarity of .Net is the problem here. You need to know what decisions the implementer of the encryption made, to come from your parameters to the encrypted string.
As far as I can see, it is the iteration count which is causing the issue. With all things the same (salt,IV,iterations), the .Net implementation generates the same output as the Java implementation. I think you may need to ask the 3rd party what iterations they are using

Difference between SALT and KEY. Encryption

Alright, so im trying to learn a little about Encrypting messages in my java application. I just found out that SALT and KEY aren't the same.
Can someone help me understand what the difference between the two is?
The key is, crudely, the equivalent of a password; you use it to encrypt a message, and then the same key gets used to decrypt it back to the original plaintext. (Well, it gets a little more complex, once you have public and private keys, and so on.)
A salt is most typically encountered with cryptographic hash functions, not encryption functions. The idea is that rather than hashing just your data (e.g. a password), you hash data+salt, where salt is typically a randomly-generated string. They have (at least) two purposes:
To foil an attacker who has access to the hashed data from identifying a collision using a rainbow table.
To slow down an attacker who's trying a brute-force attack.
The key is essentially the password with which you lock the original content.
To make the password more difficult to reverse engineer, you can add a salt to the produced encryption.
To give an obviously simple example, lets say you want to encrypt a character string. Your encryption routine is to reverse the word.
So, for the string "Hello, World", after running encryption, your string would be "dlroW ,olleH".
You could then add a salt to it. In this example, the salt will be "foo", so the result after salting would be "dlroW ,olleHfoo".
Now, if someone managed to reverse engineer your encryption algorithm, they'd get "oofHello World", which is not the original message, and thus your information is still safe!
This really comes into use when you iteratively encrypt, eg,
result = salt + encrypt(salt+encrypt(salt+encrypt(message))).

Categories