Key verification in AES - encryption

If the user enters a wrong key for AES decryption, some garbage data is generated. I want to verify the given decryption key and throw an error if the key is incorrect. How can I verify the key entered by the user?

Use an HMAC. The basic premise is that you run the plaintext through an HMAC, add the result to the plaintext and then encrypt. Then do the opposite when decrypting. If the plaintext and HMAC result match, then you know you've got the correct key.
OR, if you want to know prior to decryption, use the key material provided by the user to derive two further keys (using, say PBKDF2). Use one for encryption and another for an HMAC. In this case, encrypt first and then apply the HMAC using the second key. This way you can compute the HMAC and check if it matches before you decrypt.

Simplest approach is to add a magic number to the plaintext file data in a predictable location before encrypting; when decrypting, if the magic number is wrong, you used the wrong key. Downside to this approach is that it cannot validate the integrity/authenticity of the entire message.
To do that, use AES in an authenticated mode (e.g. AES-GCM) which gives stronger guarantees that the rest of the message was not tampered with.

One common way used to verify if a key is correctly entered, without revealing the actual key, is by use of a KCV (Key Check Value). When you create the key you would at the same time calculate the KCV, when the key is then entered manually, you can verify the entry by re-calcuylating the KCV. This is eg. used when entering keys manually into HSM's from physical key letters.
To calculate a KCV for an AES key you encrypt an empty (0x00) block with the key and the first 3 bytes of the resulting encrypted block is then the KCV.
Take a look here

Related

Not able to apply max() for Encrypted Column on SQL Server

I have a table with a datetime column that was encrypted using Always Encrypted feature on SQL Server 2016.
Now I am trying to perform this simple select:
select max(dt_order)
from orders
where customer = 123;
I am running into this error:
Msg 33299, Level 16, State 2, Line 5
Encryption scheme mismatch for columns/variables 'dt_order'. The encryption scheme for the columns/variables is (encryption_type = 'DETERMINISTIC', encryption_algorithm_name = 'AEAD_AES_256_CBC_HMAC_SHA_256', column_encryption_key_name = 'myColHML', column_encryption_key_database_name = 'TESTING') and the expression near line '1' expects it to be (encryption_type = 'PLAINTEXT') (or weaker).
In SSMS I already have set connect options "Column Encryption Setting=Enabled" and also I've set query options "Enable Parametrization for Always Encrypted"
Any idea?
Since your data is encrypted using a key on the client side, SQL Server will not be able to calculate max. This is due to the fact that SQL Server does not have the key. The main value proposition of Always Encrypted is that it protects the data from Admins of SQL Server. Currently, the only operation possible on encrypted columns is equality.
From official documentation
Deterministic encryption always generates the same encrypted value for
any given plain text value. Using deterministic encryption allows
point lookups, equality joins, grouping and indexing on encrypted
columns. However, but may also allow unauthorized users to guess
information about encrypted values by examining patterns in the
encrypted column, especially if there is a small set of possible
encrypted values, such as True/False, or North/South/East/West region.
Deterministic encryption must use a column collation with a binary2
sort order for character columns.
Randomized encryption uses a method that encrypts data in a less
predictable manner. Randomized encryption is more secure, but prevents
searching, grouping, indexing, and joining on encrypted columns.

What is a hash table that doesn't know the keys?

For example, if I create a dictionary in python I can use d.keys() to retrieve the keys.
What is a hash table/dictionary without this kind of access? Storage might be an issue and the keys may be of least importance.
Edit (clarification): I want a data structure that can access values through the key but doesn't know the key, only the hash. For example:
Hash Value
-----------------------------------------------------------------------
2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae|hey!
c9fc5d06292274fd98bcb57882657bf71de1eda4df902c519d915fc585b10190|hello!
If I try and access the data structure with the key "this is a key", it will hash that and get "hello!". If I try to access it with the key "foo", I will get "hey!".
We cannot retrieve the keys from this hash table, but we can access the data. This would be useful in cases where storage is important.
Normally, this would be the table:
Hash Value Key
-------------------------------------------------------------------------------------
2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae|hey! |foo
c9fc5d06292274fd98bcb57882657bf71de1eda4df902c519d915fc585b10190|hello!|this is a key
This is called a Set - in this case the value is the key, and implementations generally use the hashcode and equality operations on the items before adding them to the set.
Some implementations of Set can be sorted, generally those are referred to as SortedSet. Think of Set<T> as an equivalent to Dictionary<T,T> (and SortedSet<T> being approximate of SortedDictionary<T,T> in C# parlance.
Sorted variants are generally implemented using binary trees, whereas unsorted implementations use hashing tables. As the key is the value, most implementations only store the value itself.
Which platform / language are you using? Java?

How to generate unique 56 bit key for a given input string

This is part of my homework question (but this is not the actual question),
In my question professor asked me to generate a unique 56 bit key to encrypt and decrypted a message. Both the sender and receiver shares a pass-phrase (password) only. There is no key exchange here.
How to get unique 56 bit key with the help of a pass-phrase??
Can i use hash? but how to get 56 bit hash value ??
Question : (relevant part)
Messanger app:
1) Alice and Bob share the same password (or passphrase), they must use the
password to set up the tool to correctly encrypt and decrypt messages shared
between each other.
2) Each message during Internet transmission must be encrypted using a 56-bit
key
3) DONOT directly use the password as the key, you have to generate the same
key between Alice and Bob to encrypt messages.
.......
.....
The keyword is Key derivation functions

Hashing and Salting confusion

I have read a lot about hashing and salting passwords. I know how hashing works, that is all very easy, but the thing I am confused about is salting.
If I hash and salt a password and stick it into the database, how can I check that password with the password given when a user tries to log-in. Surely because the salt is completely random, it will be near-impossible to get that salt again to be able to match the database
EXAMPLE:
//On create account.
hash(password + randomSalt) to the Database
//On log-in
hash(password + differentRandomSalt) compare to Database
You generate a random hash of a fixed length with every password you hash. Then you store that salt in combination with the computed hash into one database column.
When the user wants to login, you extract the salt-part from the database and can match the results.
Example:
var salt = GenerateSecureRandom(16) // generates e.g. 0x42552241
var saltedHash = Hash(salt + password)
Login scenario:
var saltedHash = GetSaltedHashFromDatabase()
var salt = GetFirstBytes(saltedHash) // 0x42552241
var hash = GetRemainingBytes(saltedHash) // 0x47111337
var match = IsMatch(hash, salt, userInput)
A database entry could look like this (where = is the salt and * is the hash):
0x4255224147111337
========********
For (much) more details have a look at: https://crackstation.net/hashing-security.htm
The salt is random for each different user/password combination. It's not random for the same user/password combination. If that would be the case, then you would not be able to verify the password, as you already found out. If a large enough salt is generated with a sufficiently secure random number generator then it would even be impossible to verify the password. The idea of the salt is to protect against rainbow table attacks as well as creating a different password hash for different users if the password is the same.
The salt is usually stored together with the username and password hash in the database. It could be made part of a special construct that contains the salt and the password hash or it could be stored in a separate column. Sometimes the password-hash is actually a special string containing both the salt and the hash in some kind of format (using hexadecimal or base64 encoding) that needs to be parsed, but it could also a binary value simply consisting of a statically sized salt and statically sized hash.
An example bcrypt string would be:
$2a$12$QyrjMQfjgGIb4ymtdKQXIewDBqhA3eNppF8qOrMhidnEbzNvmHqhy
which is constructed as in this SO answer.
Setup:
find user
receive & verify old + password (see below)
receive new password
generate random salt
calculate hash from password and salt
store salt & hash in database with user
Verification:
find user
receive password
retrieve salt & hash for user
calculate hash to verify from password and salt
compare and return result
Usually, for security reasons, you should try and do a time-constant compare, even if that's not really an issue for password hashing. Furthermore often no distinction is made between unknown user and wrong password, simply to avoid giving information to attackers.
It makes sense to construct your password hashing scheme in such a way that it allows for updates to the amount of iterations, hash size, hash function etc.

Encrypt DES with hash MD5

I have to encrypt a text by using the DES algorythm with a hash created in MD5.
The MD5 function has the parameters: salt (byte[8]) and key (string 6), It has to iterate 1000 times. When I pass the MD5 encryption function it returns me a byte[16].
The DES function parameters are: the string to encrypt and the key (returned by the MD5 function). But when I try to assign the key value to the key encoder I get an exception because it waits a bte[8] instead of a byte[16]. I've tryed to get the first 8 bytes or the last 8 bytes..... But it doesn't work (I have an example and I have to get the same result).
Some ideas???
DES (not to be confused with 3DES) has 56 bit keys. Your problem will require more definition in order to determine the correct choice for the key.
There is no reason to use DES today. There are far better, unbroken, algorithms available.
Why are you using the hash as an encryption key? Keys should be cryptographically secure random data, something a hash is not. Hashing itself is not encryption at all.
DES keys are 56 bits normally packaged in 8 bytes, so taking the first 8 bytes from the hash means you have a key that is too long (depending on if it's signed or unsigned), you need to extract 56 bits if you must use the hash as a source.

Resources