LUKS change encryption key - encryption

I found on this forum some very interesting content for problem that I have, but I don't found answer for my question.
To change encryption password I can use command:
cryptsetup luksChangeKey /dev/sda2
... and that works. But how to encrypt /dev/sda2 partition again with new password?
If my old password is compromised and I only change password, stored data is encrypted with old password not with new.

The LUKS partition itself is not encrypted with your password: it is encrypted with a strong "master key" randomly calculated upon volume creation. Your old and new passwords only serve to encrypt the "master key". Unfortunately both passwords and the "master key" as often referred to as "keys" hence your (and others') confusion.
When in the old days cryptsetup did not rely on LUKS, every time you changed your cryptsetup password the entire disk would have to be re-encrypted!
Nowdays you only have to change your master key if someone also gains physical or administrative access to the encrypted device while the password is valid.
p.s. if not relying on temporary storage but having free space, the LUKS master key may be "changed" by shrinking a LUKS volume via "cryptsetup resize", creating another volume, moving data, deleting the first volume and expanding the second volume.

Related

How to re-add "unique" salt when user logs in?

I am learning about hashing and encryption and can’t seem to understand this:
Client: New user logs in => Creates password => Sent to a server in plain text
Server: Server generates a random "salt" => plain text and salt are unified => Hash function (e.g. SHA-3) hashes the password+salt into a hash => Hash is stored in DB.
Client: Same user logs out and logs in => Password sent to a server in plain text.
Server: Password needs to re-add the same salt it generated when creating the account to get the same hash.
How does the server generate that same random and unique salt?
Is the salt stored on a different DB altogether?
If a DB is compromised the hackers would also gain access to the salt and just brute force rainbow tables with the salt and unhash them.
The salt that was randomly generated must be stored in the database and linked to the user that logged in. It could be simply added as another column in the user table.
In a typical setting, the salt and the password (or its version after
key stretching) are concatenated and processed with a cryptographic
hash function, and the output hash value (but not the original
password) is stored with the salt in a database
Source: https://en.wikipedia.org/wiki/Salt_(cryptography) retrieved 19/02/21
The generation of the salt depends on which technology you are using. The following stack overflow answer has an example for PHP:
Can we use uniqid() to generate a unique Salt in PHP
The password should also never be sent in plain text to the server. This can be done via HTTPS for example
When the user logs in again. The password is sent to server side along with email.
The email is used to fetch the user record and then the Hash value saved against that email is compared with the new hash (salt + password entered).
The validate function method matches the 2 different hash values and checks if password entered was same or not.
For example, I am using bcrypt in Node JS and it has a method compareSync which matches the entered password with the saved hash
bcrypt.compareSync(password, databaseHash);

Crpyto system with master key and derived keys - Is this possible?

I've been doing some searching and still do not know if this is possible. What I want is for a message to by encrypted by our system and decrypted by a "master key" and also a 3rd party.
This encrypted message needs to be decrypted by 2 entities
-A 3rd party (which we want the control to shut off their ability to decrypt)
-Our system (which we want to always be able to decrypt no matter what, master key?)
From some research I was doing there is a concept of master key and derived keys
Does this following system exist?:
Master Key - can decrypt anything encrypted by derived keys
DerivedKey1 -> Encrypt data with this key and be able to decrypt with Master Key OR DerivedKey1
DerivedKey2 -> Encrypt data with this key and be able to decrypt with Master Key OR DerivedKey2 but NOT derivedKey1
Any terminology I should be using to search for answers would be helpful, also any crypto systems that do this already would be great to know.
Yes, I mean deny any new messages sent from our system to be decrypted
You can encrypt the content with a random key (data key).
Then you can encrypt the data key for each intended recipient (master key and any 3rd party) using its shared or public key.

Is brute force the only reasonable approach to detecting encryption?

An old version of an application has some passwords stored in the clear in its database. I have written an updated version that encrypts the passwords when new entries are made, but I don't have direct access to the database to manually encrypt the entries that already exist. When the update goes live, it will try to decrypt the plaintext passwords, and crash.
Short of doing something drastic like deleting all the existing data, the only other approach I can think of is this (wrapper pseudocode called when the password data is used.):
# data refers to the password data, either encrypted or plain
if data length < AES.block_size:
# (Shorter than initialization vector, definitely not encrypted.)
open database and replace password entry with encrypt(data)
login(username, data)
else:
try: # try plaintext first
login(username, data)
except AuthenticationError:
login(username, decrypt(data))
else: #plain text worked, encrypt data for future use.
open database and replace password entry with encrypt(data)
It seems a shame to keep this code around to solve a problem that goes away after it runs once. Is there any other approach that might work to ensure the passwords are encrypted and only decrypt the ones that need it?
In this scenario I do one of the following, depending on the client and the system involved:
Set up the encrypted password code, delete all existing passwords, and make everyone enter a new password. I prefer this because the passwords were plain and over time may have been seen or shared.
Run a one-time script to encrypt every password in the system. This way there is never a mix.
Have newer encrypted passwords prefixed with the encryption method, e.g. "SHA1:". You run the risk of someone having that same text as the start of their password, but it is unlikely.

Convert ASP.NET Membership Passwords from Encrypted to Hashed

I've developed a website that uses ASP.NET membership. Based on comments from previous sites, I decided to encrypt passwords so they could be recovered for users who forgot them.
However, the new site (which now has over 500 registered users) has brought me some criticism that the industry standard is really to hash passwords.
However, after a fairly extensive search, I have been unable to find anything about how to convert existing users' passwords from encrypted to hashed.
I know I can change the web.config file, and new users' passwords will use the new format. But it does nothing to update the existing users.
Note: I previously asked a similar question but mostly just got a debate about which is better, encrypted or hashed. I'm past that discussion but I've been unable to find a way to convert them without losing the hundreds of users already registered.
it seems you already know how to decrypt the passwords and change the web.config file, but you're stuck with how to implement the rest of the process.
using ILSpy, here's how to generate the salt for each user:
byte[] array = new byte[16];
new RNGCryptoServiceProvider().GetBytes(array);
return Convert.ToBase64String(array);
once you have the salt, here's how to generate the password:
byte[] bytes = Encoding.Unicode.GetBytes(pass);
byte[] array = Convert.FromBase64String(salt);
byte[] array2 = new byte[array.Length + bytes.Length];
Buffer.BlockCopy(array, 0, array2, 0, array.Length);
Buffer.BlockCopy(bytes, 0, array2, array.Length, bytes.Length);
using (SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider()) {
return Convert.ToBase64String(sha1.ComputeHash(array2));
}
where pass is the plain-text password you calculated, and salt is the string calculated in the first code snippet above. the default algorithm is SHA1, if you're wondering why it's being used.
since this is a one-time process, i would write a HTTP handler to manually update the database during a short, scheduled maintenance period - hopefully you have that luxury. (obviously make a backup and test first). you need to update the following fields in the aspnet_Membership table:
Password - calculated above
PasswordFormat - 1
PasswordSalt - calculated above
never had to do anything like this, but hopefully that will get you started :)
IMHO, Greg's response (and the associated comments) on your previous question (Changing passwordFormat from Encrypted to Hashed) is the way to go. Essentially, you want to:
Add a hashed membership provider
Loop through all of the encrypted password users,
For each one decrypt the password, create the hash, store it, delete the encrypted version from the database, and move on.
When you are done, all of the encrypted password users should be converted to hashed.
Maybe I'm missing something here, but it should be pretty simple. Create a process to decrypt the password, then salt accordingly and store the hash of the salt + user's decrypted password in the database. Obviously you don't want to be hashing the user's encrypted password. Don't forget to store the salt too.

How to Script Automated Root Password Changes?

Currently our process consists of logging into each *nix server and manually changing the password for each. My question is, what is a good way to automate this? I'm thinking of possibly a couple different ways to do this and would like input from others on what they recommend, use, etc.
One way I was thinking is a text file with a list of servers that need the password change and a script that prompts the user for the new password, stores it temporarily in the script and then remote connects into each server and runs the commands. Having a check to make sure the server is reachable or a timeout on the remote connection would be a good idea. Then have output to the console so the person running the script can see what servers were successful and which ones were not.
I was trying to think of another fully automated solution, but couldn't think of a good way to securely store the new password. Plus it is not a huge deal to me to have some user interaction and have to manually start the script as we only would need to do this 6 times a year.
Any thoughts, help, ideas would be greatly appeciated.
openssl passwd -1 $rootpw
Where $rootpw holds the string that will be your root password.
This will output a crypted string that you can just put in the file or whatever. I use this on a script that sets up virtual server instances that are provisioned from a database. I compute this hash before sending it over the network so the script that sets up the server can just use this hash instead of having to send it plain text.
To answer your question, each server would compute the hash slightly differently and result in a different hash, but all of those hashes would equate to the same password. You could use any one of these hashes and they would be functionally equivalent when used on any server, even though the actual content of the hash is different.
For example, I hashed foobar and these are the results:
rootpw=foobar
openssl passwd -1 $rootpw
$1$6pXamKGD$TKQqON1prArop7DpLOyAk1
openssl passwd -1 $rootpw
$1$4A4Mn16f$P7ap2AqNMRK8m72bG/Bve0
openssl passwd -1 $rootpw
$1$DyhsWEMX$i2wH6JpAqoHNFZ0YOBVHj/
openssl passwd -1 $rootpw
$1$m27FIj5e$LZPxVniAeUoZcuUoNHK8c/
openssl passwd -1 $rootpw
$1$qdX0NKm1$45rzxUj..LCJwWB/.fwGH0
Each of those hashes are different even when computed on the same machine but any of them can be used to equate to the password 'foobar' on any machine.
So just open /etc/shadow and paste that in there where you find the line:
root:$1$qdX0NKm1$45rzxUj..LCJwWB/.fwGH0:14415:0:99999:7:::
In my script I explode it at the :'s and update element [1] then concatenate the array back to a string and replace the string in the file. You can do it differently if you want, especially if you know the old value (which you can get by exploding it into an array).
I know this question is a few months old so you probably figured it out, but I'm putting this out there for any future googler's coming along and finding this.
You should compute whatever hash are your servers computing on a password and send passwords in this secured, hashed form, ready to put into /etc/shadow.
I do not know however how to do that in practice.

Resources