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))).
Related
public static void main(String[] args) {
String s = "text";
hash=DatatypeConverter.printHexBinary(MessageDigest.getInstance("MD5").digest(s.getBytes("UTF8")))
System.err.println(hash);
}
You can't. That's what hashing is about. This is not a API or library limitation but a mathematical one, which is there by design.
You need to understand that hashing and encryption/ decryption are two completely different things (which are often used together).
Hashing
A hash, or to be precise, a cryptographic hash, is the result of a mathematical one-way function which means it is meant to be irreversible. Once something is hashed, it is not possible to get the text that was hashed back from it. This is at least true for good hash algorithms, which are not considered broken. MD5 as well as SHA1 are considered broken, so if you need this in a security context, use SHA-256 or even SHA-512 instead. If you just need this for a checksum, MD5 should be fine.
You can just use an MD5 hash value and type it into Google and get the result back. That is not what you want from a hash function. E.g. take your the hash 1cb251ec0d568de6a929b520c4aed8d1 which is the MD5 hash of your message text and you'll get a website which shows you the original text.
Another property of a hash it that for two different inputs it should ideally never have the same output. That is of course impossible as the set of possible messages to hash is much much bigger then the set of possible hash messages as hashes have a fixed length. But it should not be possible to generate such a hash collision artificially following some algorithm or clever input.
The only way to find out what was hashed is to hash many messages (brute-force) and see if the computed hash matches the hash to be cracked. See Rainbow tables for more information on this.
Hashes are mostly used to ensure integrity i.e. no modification was done to a message sent over the network. It is often used in conjunction with encryption algorithms (that's probably where your confusion originates from) as you need more than integrity to guarantee secure communication i.e. additionally authentication (e.g. by using certificates) and confidentiality (this is provided by encryption algorithms).
Encryption
An encryption function is a function which takes a message and a key and produces a result which is not readable unless you have the key. Side note: there may be one or two keys for encryption/ decryption depending on the algorithm you use (symmetric vs. asymmetric). If you have the key, it is reversible by applying the decryption function. If it was a one-way function like a hash, encryption would make no sense, as a recipient of a message would not be able to retrieve the message.
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
So, I'm attempting to write a cryptography method that uses a hash that both the sender and the receiver know. I'm confused as to how to dehash a message.
For example, the sender sends a the message
M: 50 and hashes it
So 50 % 30 = 20.
H = 30
So after hashing, the resulting message would be 30.
How would the receiver be able to dehash the message to receive the original with knowing the hash?
There's no code or anything. Just an important concept that I wish to grasp.
EDIT: So, I have a general understanding of encryption and decryption. For the sake of understanding. How would I get the original message using RSA?
For for example,
Sender Private Key: 55,27
Sender Public Key: 55,3
Receiver Private Key: 35,29
Receiver Public Key: 35, 5
Is this possible?
What you are looking for is encrypting and decrypting. Hashing is a one way function which usually loses information making it impossible to recreate the original message.
Is there any way to receive the original message after hashing through encryption?
When you use encryption, you create some bytes which look random and can look like a long hash value. The difference is that the data can be decrypted back to the original information, whereas with hashing this is designed to be as hard as possible.
If so, which encryption/decryption method do I use?
The key decision to make is whether you want symmetric or asymmetric encryption. Symmetric is faster but requires the key for decryption be the same as encryption i.e. both the point of encryption and decryption needs to be secure. If you use asymmetric encryption, you can allow one end to either decrypt or encrypt but not both. i.e. only one end needs to be secure.
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
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