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
Related
I was currently looking for a sample AES encryption and decryption using Java and I have stumbled upon something like this as a solution:
LINK
Other solutions offered the same approach. I managed to got it to work but I just have some questions on its implementation.
Questions:
Why does the PBEKeySpec class need a password? what is it for? there
is already a key, why does it need to have an additional token or
password?
I understand that the key and salt is part of the encrypted value of
the original un-encrypted string. Why is that so? why not allow to
store the generate key and salt somewhere else?
Thanks and I appreciate any form of help. Just want to understand why it was made that way.
For easy-to-use and rock-solid java encryption library I recommend to use http://www.jasypt.org/
To your questions:
password is often used to derive the encryption key; this is needed because many algorithms require keys to meet certain properties such as length and randomness which isn't satisfied by many of the passwords normally used by people. See also https://docs.oracle.com/javase/7/docs/api/javax/crypto/spec/PBEKeySpec.html
A salt and an initialization vector are stored alongside the encrypted value (that is they are NOT encrypted) because it's convenient - you can easily retrieve them and use them to decrypt the original string. This is still safe because you typically only need these values to be unique not to be kept secret; e.g. salt helps you prevent rainbow table attacks by having a unique salt for each value.
A useful resource explaining some terminology: https://crypto.stackexchange.com/questions/3965/what-is-the-main-difference-between-a-key-an-iv-and-a-nonce
I just want to confirm my understanding of how AES works.
If company#1 is encrypting the data, and sending this data to company#2 to decrypt, and let's presume that one of them uses C# and the other Java.
As long as both are using the same shared secret key, is there anything else setting/configuration wise both parties should agree upon to make sure the data is correctly encryption and decrypted?
There is a lot that both have to agree upon:
shared secret key
How long is it? (Is key padding required?)
Is the actual key derived from another key or password with an additional salt?
Which key derivation function is used and what are their parameters? PBKDF2, bcrypt, scrypt, ...
Is the IV derived together with the key? (usually by requesting key size + IV size output from the key derivation function)
cipher characteristics:
block cipher like AES, Triple DES, Twofish, Rijndael, ...
cipher parameters such as block size in case it is variable
mode of operation like CBC, CTR, CFB, ...
for IV-based modes: How is the IV generated? Is it generated randomly and put into the container format or is it derived together with the key from a password and therefore doesn't need to be put into the ciphertext container?
for nonce-based modes like CTR: How big is the nonce (sometimes referred to as IV)?
for parametrized modes like CFB: How big is a segment?
padding mode like PKCS#7 padding (which is also referred to as PKCS#5 padding), ZeroPadding, ...
authentication (if any):
as mode of operation like GCM, EAX, SIV, ...
as separate encrypt-then-MAC/MAC-then-encrypt/encrypt-and-MAC scheme with a MAC like HMAC-SHA256, CMAC, HKDF, GHASH, ...
encoding of each component like Hex, Base32, Base64 or simply binary (no encoding)
Is everything encoded together into a textual format from the finished binary format or are the components encoded separately and concatenated together?
format:
Where to put IV/nonce/salt (if any)? (usually before the actual ciphertext)
Where to put authentication tag (if any)? (usually after the actual ciphertext)
Is Cryptographic Message Syntax applicable?
I've tried but failed to encode a string in Javascript to decode on a java server. We'd like to use the bouncycastle algorithm PBEWITHSHA256AND256BITAES-CBC-BC to decode serverside.
I've tried using crypto.js to do the encoding using the following code:
var encrypted = Crypto.AES.encrypt("it was Professor Plum in the library with the candlestick",
key,
{ mode: new Crypto.mode.CBC });
var encryptedString = Crypto.util.bytesToHex(Crypto.charenc.Binary.stringToBytes(crypted));
However this doesn't decode correctly on the server, my guess is its something to do with the SHA256 but I can't work out what it would be digesting & can't find any documentation. Does anyone know how to perform the encryption in javascript?
You need to do everything the same at both ends. You need the same key. You need the same mode (CBC) you need the same padding (use PKCS7) and you need the same IV.
Check that the actual key you are using is the same at both ends by displaying the hex, after you have run the passphrase through SHA-256. Check the hex for the IVs as well. Don't use any defaults, but explicitly pick the mode and padding to use.
If you think that it is the PBE/SHA-256 that is going wrong then you might want to look at how your text passphrase is being turned into bytes. Again, check the hex at both sides before it is passed to SHA-256. Converting text to bytes is a common source of errors. You need to be very sure what stringToBytes() is doing and that whatever you are using on the Java side is doing exactly the same.
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))).
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