Allow for encryption scheme upgrade

This commit is contained in:
Marcus Hill 2022-01-11 14:03:34 +00:00
parent 1dd55dbfe2
commit 951b03f712
5 changed files with 144 additions and 3 deletions

View File

@ -411,6 +411,16 @@ function encryptLoginEntry($login_password_cleartext){
return $login_password_ciphertext;
}
//For migrating/upgrading to the new encryption scheme
//Have to supply the master key as the cookie might not be set properly (generally requires a refresh)
function encryptUpgradeLoginEntry($login_password_cleartext, $site_encryption_master_key){
$iv = keygen();
//Encrypt the website/asset login using the master key
$ciphertext = openssl_encrypt($login_password_cleartext, 'aes-128-cbc', $site_encryption_master_key, 0, $iv);
$login_password_ciphertext = $iv . $ciphertext;
return $login_password_ciphertext;
}
?>

View File

@ -6,6 +6,7 @@ $row = mysqli_fetch_array($sql_settings);
//General
$config_api_key = $row['config_api_key'];
$config_aes_key = $row['config_aes_key']; //Legacy
$config_base_url = $row['config_base_url'];
//Mail

View File

@ -46,9 +46,11 @@ if(isset($_POST['login'])){
$user_id = $row['user_id'];
//Setup encryption session key
$user_encryption_ciphertext = $row['user_specific_encryption_ciphertext'];
$site_encryption_master_key = decryptUserSpecificKey($user_encryption_ciphertext, $password);
generateUserSessionKey($site_encryption_master_key);
if(isset($row['user_specific_encryption_ciphertext'])){
$user_encryption_ciphertext = $row['user_specific_encryption_ciphertext'];
$site_encryption_master_key = decryptUserSpecificKey($user_encryption_ciphertext, $password);
generateUserSessionKey($site_encryption_master_key);
}
if(empty($token)){
$_SESSION['logged'] = TRUE;

View File

@ -1028,6 +1028,78 @@ if(isset($_GET['update_db'])){
header("Location: " . $_SERVER["HTTP_REFERER"]);
}
if(isset($_POST['encryption_update'])){
$password = $_POST['password'];
//$session_company_id
//Get user details
$sql = mysqli_query($mysqli,"SELECT * FROM users WHERE user_id = '$session_user_id'");
$row = mysqli_fetch_array($sql);
//Verify the users password
if(!password_verify($password, $row['user_password'])){
echo "Password incorrect.";
exit();
}
//First, check if this user is setup for the new encryption setup
if(isset($row['user_specific_encryption_ciphertext'])){
echo "Ciphertext data already exists, using it.<br>";
$user_encryption_ciphertext = $row['user_specific_encryption_ciphertext'];
$site_encryption_master_key = decryptUserSpecificKey($user_encryption_ciphertext, $password);
}
else{
echo "Ciphertext data not found, attempting to adding it.";
$update_table = mysqli_query($mysqli, "ALTER TABLE `users` ADD `user_specific_encryption_ciphertext` VARCHAR(200) NULL AFTER `user_avatar`; ");
if(!$update_table){
echo "Error adding ciphertext column to users table. Either there was a connection/permissions issue or the column already exists due to a upgrade already taking place?<br>";
exit();
}
echo "Ciphertext column added successfully!<br>";
echo "Generating new master key.<br>";
$site_encryption_master_key = keygen();
echo "New master key is: $site_encryption_master_key <br>";
$user_encryption_ciphertext = setupFirstUserSpecificKey($password, $site_encryption_master_key);
$set_user_specific_key = mysqli_query($mysqli, "UPDATE users SET user_specific_encryption_ciphertext = '$user_encryption_ciphertext' user_id = '$session_user_id'");
if(!$set_user_specific_key){
echo "Something went wrong adding your user specific key.<br>";
exit();
}
//Setup the user session key
generateUserSessionKey($site_encryption_master_key);
//Invalidate user passwords
//If we don't do this, users won't be able to see the new passwords properly, and could potentially add passwords that can never be decrypted
mysqli_query($mysqli, "UPDATE users SET login_password = 'Invalid due to upgrade'");
$extended_log_description = ", invalidated all user passwords";
echo "Invalidated all user passwords. You must re-set them from this user.<br>";
}
//Either way, if we got here we now have the master key as $site_encryption_master_key
//Get & upgrade user login encryption
$sql_logins = mysqli_query($mysqli,"SELECT *, AES_DECRYPT(login_password, '$config_aes_key') AS login_password FROM logins WHERE (company_id = '$session_company_id' AND login_password IS NOT NULL)");
$count = 0;
foreach ($sql_logins as $row){
$login_id = $row['login_id'];
$new_encrypted_password = encryptUpgradeLoginEntry($row['login_password'], $site_encryption_master_key);
mysqli_query($mysqli, "UPDATE logins SET login_password = '$new_encrypted_password' WHERE login_id = '$login_id'");
$count++;
}
echo "Upgraded $count records.<br>";
//Logging
mysqli_query($mysqli,"INSERT INTO logs SET log_type = 'Settings', log_action = 'Migrate', log_description = '$session_name upgraded $session_company_id logins to the new encryption scheme$extended_log_description', log_ip = '$session_ip', log_user_agent = '$session_user_agent', log_created_at = NOW(), log_user_id = $session_user_id, company_id = $session_company_id");
echo "Migration for company successful.";
}
if(isset($_POST['add_client'])){
$name = trim(strip_tags(mysqli_real_escape_string($mysqli,$_POST['name'])));

View File

@ -61,4 +61,60 @@ $git_log = shell_exec("git log master..origin/master --pretty=format:'<tr><td>%h
</div>
</div>
<!-- Updater to upgrade to new encryption -->
<div class="card card-dark">
<div class="card-header">
<h3 class="card-title"><i class="fa fa-fw fa-wrench"></i> Update AES Key</h3>
</div>
<div class="card-body">
<center>
<div class="col-8">
<div class="alert alert-danger" role="alert">
<strong>You only need to continue with this action if you are upgrading/migrating to the new encryption setup.</strong>
<ul>
<li>Please take a backup of your current AES config key (for each company), and your 'logins' database table</li>
<li>Please ensure you have access to ALL companies registered under this instance, if using multiple companies. Only one user should perform the entire migration.</li>
<li>This activity will invalidate all existing user passwords. You must set them again using THIS user account.</li>
</ul>
</div>
</div>
<?php
//Get current settings
include_once('get_settings.php');
echo "Current Company ID: $session_company_id <br>";
echo "Current User ID: $session_user_id <br>";
if ($config_aes_key) {
echo "Current AES key: $config_aes_key <br><br>";
echo "<b>Below are the decrypted credentials for five login entries, please confirm they show and are correct before continuing. <br>Do NOT continue if no entries are shown or if the decrypted passwords are incorrect.</b><br>";
$sql = mysqli_query($mysqli,"SELECT *, AES_DECRYPT(login_password, '$config_aes_key') AS login_password FROM logins WHERE (company_id = '$session_company_id' AND login_password IS NOT NULL) LIMIT 5");
foreach ($sql as $row){
echo $row['login_username'] . ":" . $row['login_password'];
echo "<br>";
}
echo "<br>";
?>
<form method="POST" action="post.php">
<div class="form-group">
<div class="input-group col-3">
<input type="password" class="form-control" placeholder="Account Password" name="password" value="" required="">
</div>
<br>
<button type="submit" class="btn btn-danger" name="encryption_update">Update encryption scheme for this company</button>
</div>
</form>
<?php
}
else {
echo "Config AES key is not set for this company.<br>";
echo "Please ensure upgrade is required. If you are sure you need to update, ensure the AES key is for this company.";
}
?>
</center>
</div>
</div>
<?php include("footer.php");