diff --git a/client_logins.php b/client_logins.php index d56f2468..448f5c29 100644 --- a/client_logins.php +++ b/client_logins.php @@ -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"; } - $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 = "-"; diff --git a/functions.php b/functions.php index 0bac4894..70a583c9 100644 --- a/functions.php +++ b/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; +} + + + ?> \ No newline at end of file diff --git a/post.php b/post.php index 31919d47..0ad20415 100644 --- a/post.php +++ b/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']; ?>