mirror of https://github.com/itflow-org/itflow
Add per-user password encryption using master key
This commit is contained in:
parent
a56d701a8a
commit
49d895040a
|
|
@ -41,7 +41,7 @@ if(isset($_GET['o'])){
|
|||
//Rebuild URL
|
||||
$url_query_strings_sb = http_build_query(array_merge($_GET,array('sb' => $sb, 'o' => $o)));
|
||||
|
||||
$sql = mysqli_query($mysqli,"SELECT SQL_CALC_FOUND_ROWS *, AES_DECRYPT(login_password, '$config_aes_key') AS login_password FROM logins
|
||||
$sql = mysqli_query($mysqli,"SELECT SQL_CALC_FOUND_ROWS * FROM logins
|
||||
WHERE login_client_id = $client_id
|
||||
AND (login_name LIKE '%$q%' OR login_username LIKE '%$q%' OR login_uri LIKE '%$q%')
|
||||
ORDER BY $sb $o LIMIT $record_from, $record_to");
|
||||
|
|
@ -112,7 +112,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli,"SELECT FOUND_ROWS()"));
|
|||
}else{
|
||||
$login_username_display = "$login_username<button class='btn btn-sm' data-clipboard-text='$login_username'><i class='far fa-copy text-secondary'></i></button>";
|
||||
}
|
||||
$login_password = htmlentities($row['login_password']);
|
||||
$login_password = htmlentities(decryptLoginEntry($row['login_password']));
|
||||
$login_otp_secret = $row['login_otp_secret'];
|
||||
if(empty($login_otp_secret)){
|
||||
$otp_display = "-";
|
||||
|
|
|
|||
131
functions.php
131
functions.php
|
|
@ -159,15 +159,15 @@ function get_device(){
|
|||
}
|
||||
}
|
||||
if ($tablet_browser > 0) {
|
||||
// do something for tablet devices
|
||||
//do something for tablet devices
|
||||
return 'Tablet';
|
||||
}
|
||||
else if ($mobile_browser > 0) {
|
||||
// do something for mobile devices
|
||||
//do something for mobile devices
|
||||
return 'Mobile';
|
||||
}
|
||||
else {
|
||||
// do something for everything else
|
||||
//do something for everything else
|
||||
return 'Computer';
|
||||
}
|
||||
}
|
||||
|
|
@ -287,4 +287,129 @@ function mkdir_missing($dir) {
|
|||
}
|
||||
}
|
||||
|
||||
//Called during initial setup
|
||||
//Encrypts the master key with the user's password
|
||||
function setupFirstUserSpecificKey($user_password, $site_encryption_master_key){
|
||||
$iv = keygen();
|
||||
$salt = keygen();
|
||||
|
||||
//Generate 128-bit (16 byte/char) kdhash of the users password
|
||||
$user_password_kdhash = hash_pbkdf2('sha256', $user_password, $salt, 100000, 16);
|
||||
|
||||
//Encrypt the master key with the users kdf'd hash and the IV
|
||||
$ciphertext = openssl_encrypt($site_encryption_master_key, 'aes-128-cbc', $user_password_kdhash, 0, $iv);
|
||||
|
||||
$user_encryption_ciphertext = $salt . $iv . $ciphertext;
|
||||
|
||||
return $user_encryption_ciphertext;
|
||||
}
|
||||
|
||||
/*
|
||||
For additional users / password changes
|
||||
New Users: Requires the admin setting up their account have the their own Specific/Session key configured
|
||||
Password Changes: Will use the current info in the session. Maybe a good idea force logout users after a password change, so that upon login new session info is set fresh..
|
||||
-- This logic will need to be in the pass change function itself
|
||||
*/
|
||||
function encryptUserSpecificKey($user_password){
|
||||
$iv = keygen();
|
||||
$salt = keygen();
|
||||
|
||||
//Get the session info.
|
||||
$user_encryption_session_ciphertext = $_SESSION['user_encryption_session_ciphertext'];
|
||||
$user_encryption_session_iv = $_SESSION['user_encryption_session_iv'];
|
||||
$user_encryption_session_key = $_COOKIE['user_encryption_session_key'];
|
||||
|
||||
//Decrypt the session key to get the master key
|
||||
$site_encryption_master_key = openssl_decrypt($user_encryption_session_ciphertext, 'aes-128-cbc', $user_encryption_session_key, 0, $user_encryption_session_iv);
|
||||
|
||||
//Generate 128-bit (16 byte/char) kdhash of the users (new) password
|
||||
$user_password_kdhash = hash_pbkdf2('sha256', $user_password, $salt, 100000, 16);
|
||||
|
||||
//Encrypt the master key with the users kdf'd hash and the IV
|
||||
$user_encryption_ciphertext = openssl_encrypt($site_encryption_master_key, 'aes-128-cbc', $user_password_kdhash, 0, $iv);
|
||||
|
||||
return $user_encryption_ciphertext;
|
||||
|
||||
}
|
||||
|
||||
//Given a ciphertext (incl. IV) and the user's password, returns the site master key
|
||||
//Ran at login, to facilitate generateUserSessionKey
|
||||
function decryptUserSpecificKey($user_encryption_ciphertext, $user_password){
|
||||
//Get the IV, salt and ciphertext
|
||||
$salt = substr($user_encryption_ciphertext, 0, 16);
|
||||
$iv = substr($user_encryption_ciphertext, 16, 16);
|
||||
$ciphertext = substr($user_encryption_ciphertext, 32);
|
||||
|
||||
//Generate 128-bit (16 byte/char) kdhash of the users password
|
||||
$user_password_kdhash = hash_pbkdf2('sha256', $user_password, $salt, 100000, 16);
|
||||
|
||||
//Use this hash to get the original/master key
|
||||
$site_encryption_master_key = openssl_decrypt($ciphertext, 'aes-128-cbc', $user_password_kdhash, 0, $iv);
|
||||
return $site_encryption_master_key;
|
||||
}
|
||||
|
||||
/*
|
||||
Generates what is probably best described as an session key (ephemeral-ish)
|
||||
- Allows us to store the master key on the server whilst the user is using the application, without prompting to type their password everytime they want to decrypt a credential
|
||||
- Ciphertext/IV is stored on the server in the users session, encryption key is controlled/provided by the user as a cookie
|
||||
- Only the user can decrypt their session ciphertext to get the master key
|
||||
- Encryption key never hits the disk in cleartext
|
||||
*/
|
||||
function generateUserSessionKey($site_encryption_master_key){
|
||||
|
||||
//Generate both of these using keygen()
|
||||
$user_encryption_session_key = keygen();
|
||||
$user_encryption_session_iv = keygen();
|
||||
$user_encryption_session_ciphertext = openssl_encrypt($site_encryption_master_key, 'aes-128-cbc', $user_encryption_session_key, 0, $user_encryption_session_iv);
|
||||
|
||||
//Store ciphertext in the user's session
|
||||
$_SESSION['user_encryption_session_ciphertext'] = $user_encryption_session_ciphertext;
|
||||
$_SESSION['user_encryption_session_iv'] = $user_encryption_session_iv;
|
||||
|
||||
//Give the user "their" key as a cookie
|
||||
setcookie("user_encryption_session_key", $user_encryption_session_key, 0, "/", "", "true", "true");
|
||||
}
|
||||
|
||||
//Decrypts an encrypted password (website/asset login), returns it as a string
|
||||
function decryptLoginEntry($login_password_ciphertext){
|
||||
|
||||
//Split the login into IV and Ciphertext
|
||||
$login_iv = substr($login_password_ciphertext, 0, 16);
|
||||
$login_ciphertext = $salt = substr($login_password_ciphertext, 16);
|
||||
|
||||
//Get the user session info.
|
||||
$user_encryption_session_ciphertext = $_SESSION['user_encryption_session_ciphertext'];
|
||||
$user_encryption_session_iv = $_SESSION['user_encryption_session_iv'];
|
||||
$user_encryption_session_key = $_COOKIE['user_encryption_session_key'];
|
||||
|
||||
//Decrypt the session key to get the master key
|
||||
$site_encryption_master_key = openssl_decrypt($user_encryption_session_ciphertext, 'aes-128-cbc', $user_encryption_session_key, 0, $user_encryption_session_iv);
|
||||
|
||||
//Decrypt the login password using the master key
|
||||
$login_password_cleartext = openssl_decrypt($login_ciphertext, 'aes-128-cbc', $site_encryption_master_key, 0, $login_iv);
|
||||
return $login_password_cleartext;
|
||||
|
||||
}
|
||||
|
||||
//Encrypts a website/asset login password
|
||||
function encryptLoginEntry($login_password_cleartext){
|
||||
$iv = keygen();
|
||||
|
||||
//Get the user session info.
|
||||
$user_encryption_session_ciphertext = $_SESSION['user_encryption_session_ciphertext'];
|
||||
$user_encryption_session_iv = $_SESSION['user_encryption_session_iv'];
|
||||
$user_encryption_session_key = $_COOKIE['user_encryption_session_key'];
|
||||
|
||||
//Decrypt the session key to get the master key
|
||||
$site_encryption_master_key = openssl_decrypt($user_encryption_session_ciphertext, 'aes-128-cbc', $user_encryption_session_key, 0, $user_encryption_session_iv);
|
||||
|
||||
//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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
?>
|
||||
8
post.php
8
post.php
|
|
@ -4439,14 +4439,14 @@ if(isset($_POST['add_login'])){
|
|||
$name = trim(strip_tags(mysqli_real_escape_string($mysqli,$_POST['name'])));
|
||||
$uri = trim(strip_tags(mysqli_real_escape_string($mysqli,$_POST['uri'])));
|
||||
$username = trim(strip_tags(mysqli_real_escape_string($mysqli,$_POST['username'])));
|
||||
$password = trim(mysqli_real_escape_string($mysqli,$_POST['password']));
|
||||
$password = trim(mysqli_real_escape_string($mysqli,encryptLoginEntry($_POST['password'])));
|
||||
$otp_secret = trim(strip_tags(mysqli_real_escape_string($mysqli,$_POST['otp_secret'])));
|
||||
$note = trim(strip_tags(mysqli_real_escape_string($mysqli,$_POST['note'])));
|
||||
$vendor_id = intval($_POST['vendor']);
|
||||
$asset_id = intval($_POST['asset']);
|
||||
$software_id = intval($_POST['software']);
|
||||
|
||||
mysqli_query($mysqli,"INSERT INTO logins SET login_name = '$name', login_uri = '$uri', login_username = '$username', login_password = AES_ENCRYPT('$password','$config_aes_key'), login_otp_secret = '$otp_secret', login_note = '$note', login_created_at = NOW(), login_vendor_id = $vendor_id, login_asset_id = $asset_id, login_software_id = $software_id, login_client_id = $client_id, company_id = $session_company_id");
|
||||
mysqli_query($mysqli,"INSERT INTO logins SET login_name = '$name', login_uri = '$uri', login_username = '$username', login_password = '$password', login_otp_secret = '$otp_secret', login_note = '$note', login_created_at = NOW(), login_vendor_id = $vendor_id, login_asset_id = $asset_id, login_software_id = $software_id, login_client_id = $client_id, company_id = $session_company_id");
|
||||
|
||||
//Logging
|
||||
mysqli_query($mysqli,"INSERT INTO logs SET log_type = 'Login', log_action = 'Created', log_description = '$name', log_created_at = NOW(), company_id = $session_company_id, log_user_id = $session_user_id");
|
||||
|
|
@ -5681,7 +5681,7 @@ if(isset($_GET['export_client_pdf'])){
|
|||
$sql_locations = mysqli_query($mysqli,"SELECT * FROM locations WHERE location_client_id = $client_id ORDER BY location_name ASC");
|
||||
$sql_vendors = mysqli_query($mysqli,"SELECT * FROM vendors WHERE vendor_client_id = $client_id ORDER BY vendor_name ASC");
|
||||
if(isset($_GET['passwords'])){
|
||||
$sql_logins = mysqli_query($mysqli,"SELECT *, AES_DECRYPT(login_password, '$config_aes_key') AS login_password FROM logins WHERE login_client_id = $client_id ORDER BY login_name ASC");
|
||||
$sql_logins = mysqli_query($mysqli,"SELECT * FROM logins WHERE login_client_id = $client_id ORDER BY login_name ASC");
|
||||
}
|
||||
$sql_assets = mysqli_query($mysqli,"SELECT * FROM assets WHERE asset_client_id = $client_id ORDER BY asset_type ASC");
|
||||
$sql_networks = mysqli_query($mysqli,"SELECT * FROM networks WHERE network_client_id = $client_id ORDER BY network_name ASC");
|
||||
|
|
@ -6022,7 +6022,7 @@ if(isset($_GET['export_client_pdf'])){
|
|||
while($row = mysqli_fetch_array($sql_logins)){
|
||||
$login_name = $row['login_name'];
|
||||
$login_username = $row['login_username'];
|
||||
$login_password = $row['login_password'];
|
||||
$login_password = decryptLoginEntry($row['login_password']);
|
||||
$login_uri = $row['login_uri'];
|
||||
$login_note = $row['login_note'];
|
||||
?>
|
||||
|
|
|
|||
Loading…
Reference in New Issue