All descriptions of the AES-128 algorithm that I've found on the inter-web talk about inputting a 128 bit plaintext that undergoes 11 rounds of transformations to produce a 128 bit cipher text. My question is:
Since the actual message to be sent can occupy more than just a single 128 bit "block", do I need a unique key for each 128 bit block that I generate from my message to be encrypted using AES-128, or can I use the same key for each of those 128 bit blocks?
I need this information in regards to creating an algorithm for a paper (journal), so I need to be scientifically correct in my use of AES-128, which forms a part of my algorithm.
You may want to have a look at Block_cipher_mode_of_operation.
If you use the same key for every block, you are using the Electronic codebook (ECB). However this mode of operation is not recomended.
Something more secure would be the Galois/Counter mode or the Cipher block chaining mode. For more information read the wiki article.
I'm not familiar with FIPS PUB-197, but I know the security properties of AES.
AES is a block cipher and all block ciphers are modeled in such a way that you cannot deduce the key even if you know both ciphertext and plaintext. With this property, you can follow that using the same key for multiple blocks is perfectly secure even if parts of the plaintext and ciphertext are known to the attacker. This property emerges after cryptanalysis that is done by cryptographers when they want to find holes in an algorithm like AES.
Also, if you have 11 rounds for a 128 bit key, you don't have AES, but something else.
The current top-voted to this question states:
Another one that's not so much a security issue, although it is security-related, is complete and abject failure to grok the difference between hashing a password and encrypting it. Most commonly found in code where the programmer is trying to provide unsafe "Remind me of my password" functionality.
What exactly is this difference? I was always under the impression that hashing was a form of encryption. What is the unsafe functionality the poster is referring to?
Hashing is a one way function (well, a mapping). It's irreversible, you apply the secure hash algorithm and you cannot get the original string back. The most you can do is to generate what's called "a collision", that is, finding a different string that provides the same hash. Cryptographically secure hash algorithms are designed to prevent the occurrence of collisions. You can attack a secure hash by the use of a rainbow table, which you can counteract by applying a salt to the hash before storing it.
Encrypting is a proper (two way) function. It's reversible, you can decrypt the mangled string to get original string if you have the key.
The unsafe functionality it's referring to is that if you encrypt the passwords, your application has the key stored somewhere and an attacker who gets access to your database (and/or code) can get the original passwords by getting both the key and the encrypted text, whereas with a hash it's impossible.
People usually say that if a cracker owns your database or your code he doesn't need a password, thus the difference is moot. This is naïve, because you still have the duty to protect your users' passwords, mainly because most of them do use the same password over and over again, exposing them to a greater risk by leaking their passwords.
Hashing is a one-way function, meaning that once you hash a password it is very difficult to get the original password back from the hash. Encryption is a two-way function, where it's much easier to get the original text back from the encrypted text.
Plain hashing is easily defeated using a dictionary attack, where an attacker just pre-hashes every word in a dictionary (or every combination of characters up to a certain length), then uses this new dictionary to look up hashed passwords. Using a unique random salt for each hashed password stored makes it much more difficult for an attacker to use this method. They would basically need to create a new unique dictionary for every salt value that you use, slowing down their attack terribly.
It's unsafe to store passwords using an encryption algorithm because if it's easier for the user or the administrator to get the original password back from the encrypted text, it's also easier for an attacker to do the same.
As shown in the above image, if the password is encrypted it is always a hidden secret where someone can extract the plain text password. However when password is hashed, you are relaxed as there is hardly any method of recovering the password from the hash value.
Extracted from Encrypted vs Hashed Passwords - Which is better?
Is encryption good?
Plain text passwords can be encrypted using symmetric encryption algorithms like DES, AES or with any other algorithms and be stored inside the database. At the authentication (confirming the identity with user name and password), application will decrypt the encrypted password stored in database and compare with user provided password for equality. In this type of an password handling approach, even if someone get access to database tables the passwords will not be simply reusable. However there is a bad news in this approach as well. If somehow someone obtain the cryptographic algorithm along with the key used by your application, he/she will be able to view all the user passwords stored in your database by decryption. "This is the best option I got", a software developer may scream, but is there a better way?
Cryptographic hash function (one-way-only)
Yes there is, may be you have missed the point here. Did you notice that there is no requirement to decrypt and compare? If there is one-way-only conversion approach where the password can be converted into some converted-word, but the reverse operation (generation of password from converted-word) is impossible. Now even if someone gets access to the database, there is no way that the passwords be reproduced or extracted using the converted-words. In this approach, there will be hardly anyway that some could know your users' top secret passwords; and this will protect the users using the same password across multiple applications. What algorithms can be used for this approach?
I've always thought that Encryption can be converted both ways, in a way that the end value can bring you to original value and with Hashing you'll not be able to revert from the end result to the original value.
Hashing algorithms are usually cryptographic in nature, but the principal difference is that encryption is reversible through decryption, and hashing is not.
An encryption function typically takes input and produces encrypted output that is the same, or slightly larger size.
A hashing function takes input and produces a typically smaller output, typically of a fixed size as well.
While it isn't possible to take a hashed result and "dehash" it to get back the original input, you can typically brute-force your way to something that produces the same hash.
In other words, if a authentication scheme takes a password, hashes it, and compares it to a hashed version of the requires password, it might not be required that you actually know the original password, only its hash, and you can brute-force your way to something that will match, even if it's a different password.
Hashing functions are typically created to minimize the chance of collisions and make it hard to just calculate something that will produce the same hash as something else.
Hashing:
It is a one-way algorithm and once hashed can not rollback and this is its sweet point against encryption.
Encryption
If we perform encryption, there will a key to do this. If this key will be leaked all of your passwords could be decrypted easily.
On the other hand, even if your database will be hacked or your server admin took data from DB and you used hashed passwords, the hacker will not able to break these hashed passwords. This would actually practically impossible if we use hashing with proper salt and additional security with PBKDF2.
If you want to take a look at how should you write your hash functions, you can visit here.
There are many algorithms to perform hashing.
MD5 - Uses the Message Digest Algorithm 5 (MD5) hash function. The output hash is 128 bits in length. The MD5 algorithm was designed by Ron Rivest in the early 1990s and is not a preferred option today.
SHA1 - Uses Security Hash Algorithm (SHA1) hash published in 1995. The output hash is 160 bits in length. Although most widely used, this is not a preferred option today.
HMACSHA256, HMACSHA384, HMACSHA512 - Use the functions SHA-256, SHA-384, and SHA-512 of the SHA-2 family. SHA-2 was published in 2001. The output hash lengths are 256, 384, and 512 bits, respectively,as the hash functions’ names indicate.
Ideally you should do both.
First Hash the pass password for the one way security. Use a salt for extra security.
Then encrypt the hash to defend against dictionary attacks if your database of password hashes is compromised.
As correct as the other answers may be, in the context that the quote was in, hashing is a tool that may be used in securing information, encryption is a process that takes information and makes it very difficult for unauthorized people to read/use.
Here's one reason you may want to use one over the other - password retrieval.
If you only store a hash of a user's password, you can't offer a 'forgotten password' feature.
I recently read that MD5 is not secure because it can be traced within a small amount of time.
If I give only a fixed 512 bit data as input.
MD5 will give 128 bit hash (32 hex values)
If MD5 is flawed, then can anyone suggest the best way to reconstruct the 512 bit input, given the 128 bit hash?
(Side note: I badly want to implement this. Would C++ be a better choice for speed or Java for its inbuilt security packages?)
There are 2 ** 384 (about 4x10**115) different 512-bit blocks that hash to the same MD5. Reversing isn't possible even in principle.
It is possible, however, to find one of those 4x10**115 blocks that produces the same MD5 as the block you want, and that's why it's considered insecure. For example, if you posted a file to the net along with an MD5 hash to verify its integrity, a hacker might be able to replace it with a different file with the same hash.
With a more secure hash like SHA256, even this wouldn't be possible.
MD5 is simple and fast algorithm especially when implemented using GPU, so it can be cracked by brute force that is why it is not 'secure'.
But the typical context in which it is insecure is in the respect of passwords which have limited number of characters and their typical combinations (dictionary worlds)
For 512bit long message the brute force would take too long even with MD5, it is equivalent to 64 characters passwords, currently the brute force attack limit is around 10 characters.
The RSA implementation that ships with
Bouncy Castle only allows the
encrypting of a single block of data.
The RSA algorithm is not suited to
streaming data and should not be used
that way. In a situation like this you
should encrypt the data using a
randomly generated key and a symmetric
cipher, after that you should encrypt
the randomly generated key using RSA,
and then send the encrypted data and
the encrypted random key to the other
end where they can reverse the process
(ie. decrypt the random key using
their RSA private key and then decrypt
the data).
I can't use the workaround of using symmetric key. So, are there other implementations of RSA than Bouncy Castle?
This restriction isn't just something randomly invented by Bouncy Castle, and using a symmetric key isn't a "workaround": it's correct practice.
The RSA algorithm is intrinsically not suited to encrypting large quantities of data. If you really really really really really want to use it on a large quantity of data, then you could just about split your data up into blocks small enough, and encrypt each one. But this is not standard practice and you could run into security issues you haven't thought of, whereas block ciphers such as AES have standard means for dealing with the issues you may come across (look at block modes-- essentially there's a security issue for example encrypting the same data with the same key multiple times, and block modes are a built in way to deal with this).
I would really just stick to the standard practice of streaming with symmetric encryption and encrypting the symmetric key (and essentially nothing else) with RSA.
Yes, the JDK comes with one but it won't do you any good. Typically, this is the way encryption is done when using RSA. You generate a random symmetric key and encrypt your data with that. You encrypt the symmetric key with RSA and transmit.
If you want to encrypt only with RSA and leave out the symmetric part you can do that (with BC or without) but be warned that it's going to be awfully slow to encrypt or decrypt and take up a LOT more space than the typical alternative.
All RSA implementations would have a similar caveat. That's the nature of the RSA algorithm.
Using a symmetric key as described isn't a "workaround". It's "correct." If there's any possibility of applying a better encryption technique, it would be worth pursuing.
You can invoke RSA once for each data "block". Don't do this.
RSA isn't a block cipher. It accepts inputs in the range [0,p×q], not [0,2n−1]. In the obvious implementation, each output block is at least 1 bit larger than an input block, which is not ideal.
RSA is multiplicative. Using RSAe() to mean RSA encryption with key e,
RSAe(0) = 0
RSAe(1) = 1
RSAe(a*b) = RSAe(a) × RSAe(a)
Why can't you generate a symmetric key?
I am encrypting an string with PBEWITHSHA256AND128BITAES-CBC-BC using SealedObject and write it to a file. After encrypting when i do a cat on the resulting file i i get read the salt used and the algorithm used in plain text even though the actual data is encrypted.
Doesn't that give crackers a head start? They know the salt and the algorithm with basically zero effort.
The salt isn't secret. Its purpose is generally to prevent dictionary attacks.
Keeping the algorithm secret is security through obscurity, which is pretty much universally discouraged.
When you use PBE (Password-Based Encryption), salt and iteration are just to make cracking more expensive. You only need to generate key once but guessers will have to try millions.
If you require salt to be secret, it defeats the purpose of the password. Password is something easy to remember but less secure. If you really worried about security, don't use password. Use a secret key.
Hiding salt is practically a double key scheme. In most cases, it doesn't make your cipher much stronger.