I'm having a problem where my password doesn't store after encryption even though it stores perfectly when I don't encrypt it. When I go to the database to check whether it's stored or not, I just see a blank under the password column. I want my password's encoding to be UTF-8 (or whatever it's called) since I want to use the Arabic language in my database.
PHP CODE
$password = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $_POST['password'], MCRYPT_MODE_CBC, $iv);
base64_encode($password);
Here's a picture that will show you my table's structure :
http://prntscr.com/91nhyx
You need to store the base64 encoded version before storing it in the database:
$password = base64_encode($password);
Related
I know saving passwords in plain text is in a database is bad, but I need to save the password in a way that the users can retrieve and view them.
The Database will be located within our web host and access to it will be restricted to known IP Addresses, the actual scripts that will be accessing the database will be located in a different datacentre which is locked down for all access to our specific known IP Addresses.
What I'm thinking of doing is creating an encryption key based on the unique school name, location and a 64 digit string. This will secure the password which will then be saved into the database.
To decrypt this, the script will have to read the school name and location from the DB and add the 64 digit string and then decrypt the password to display to the user.
When this goes live the 64 digit string won't be saved in the script it will be passed on the URL.
Using this https://stackoverflow.com/a/57249681/2134973 I've managed to get the password to be encrypted and decrypted. But as soon as I save the encrypted password to the database, it fails to decrypt when read back from the Database.
The code I have so far is:
From the initial database read I have :
$school = $db['school'];
$location = $db['location'];
$password = $db['password']; // plain text
I then encrypt using:
define('ENCRYPTION_KEY', "{$school}r$qVsYRk4*&H?=pb9sRdJHLbtERBwGSxezJa5eG?Zb#SrC&q2yzHLE=BjU?Wm9sM{$location}");
$OpensslEncryption = new Openssl_EncryptDecrypt;
$encrypted = $OpensslEncryption->encrypt($password, ENCRYPTION_KEY);
and save $encrypted back to my database.
For decrypting it I'm reading the data from the database and processing it as:
$school = $db['school'];
$location = $db['location'];
$password = $db['password']; // encrypted
define('ENCRYPTION_KEY', "{$school}r$qVsYRk4*&H?=pb9sRdJHLbtERBwGSxezJa5eG?Zb#SrC&q2yzHLE=BjU?Wm9sM{$location}");
$OpensslEncryption = new Openssl_EncryptDecrypt;
$decrypted = $OpensslEncryption->decrypt($password, ENCRYPTION_KEY);
If I var_dump $decrypted I get NULL.
If I dump the $encrypted and $password (after encryption) they are both the same string length.
The field in the database is defined as VARCHAR 1024
Can anyone advise how to do this, or if there is a better more secure way.
Ultimately I need to user to be able to see the passwords as plain text, but store them as securely as possible.
Thanks
UPDATE
The password held in the database don't belong to the users who are logged in. They are passwords to our internal systems which are all IP authenticated as well.
The users need to see these passwords.
I want to store a base64_encoded string as binary data. So use base64_decode() on the string before inserting in a LONGBLOB field of MySQL. So far so good, however when I retrieve the data from MySQL, I can't generate the correct base64_encoded string which I have started with...
How is this possible? Thanks in advance
EDIT
The stored data is an encrypted string with AES-256CBC OPENSSL encryption routine.
CODE
For my code I use OpenSSL to encrypt a string
$string = "Test";
$IV = "1234567890123456";
$key = "12345678901234561234567890123456";
$encrypted = openssl_encrypt($string, "AES-256-CBC", $key, false, $IV);
$encrypted string is stored in LONGBLOB field by
$sql_insert_data = $mysqli->prepare("INSERT INTO `TBLName` (String) Values(?)");
$sql_insert_data->bind_param('s', $mysqli->real_escape_string($encrypted));
//Thereafter, it is retrieved by a select statement
$decrypted = openssl_decrypt($row['String'], "AES-256-CBC", $key, true, $IV);
When I do base64_encode on the string and store that as a TEXT value in the DB, the above works. However, when I do not, the above does not work...
Thanks
You are using prepared statements incorrectly:
$sql_insert_data->bind_param('s', $mysqli->real_escape_string($encrypted));
^^^^^^^^^^^^^^^^^^ :-!
Your code will add random backslashes to the binary stream. You don't need real_escape_string() at all.
"damn son, the question is how to I optimize the storage of base64_encoded data successfully in mysql. That's all." -- See https://stackoverflow.com/a/42080296/1766831
Kindly I am a developer with basics of encryption ,
I have a task which is encrypting data then save the encryption to database,
I am using openssl php function to encrypte and decrypte like below
function encrypte($stringToEncrypte){
$method="AES-128-CBC";
$iv=mcrypt_create_iv(16, MCRYPT_RAND);
$pass=md5('8123jhewe8dnjsdnq');
$encrypted=openssl_encrypt ($stringToEncrypte, $method, $pass, true , $iv);
return $encrypted."---".$iv;
}
function decrypte($stringToDecrypte){
/*
decrypte by remove --- then get iv then get encrypted then decrypte
*/
}
It's working fine but the encrypted text has random encoding and this will cause many errors in saving correctly into my database which saving in UTF-8 Encoding.
Definitely, I tried to convert the encrypted key to utf-8 by mb_convert_encoding() function but logically , the new encoded text will not be decrypted correctly , because the new encoded text will not be the same of the old encoded text .
For example, the encrypted text will have random encoding like ISO-8859-1
and my database encoding is utf-8 and encoding conversion will not generate text could be decrypted again.
i found something may by not very bad ,is to use URLencode PHP function , i tried it and it was working fine ,
but still i need experts answer
If your database is utf8, than all your content should be utf8. You need to convert your $stringToEncrypte to utf8 before you encrypt it. And make shure your $pass and $iv are utf8 as well. Then you can encrypt (also utf8), save in database and decrypt everything in utf8 as well.
I use openssl to encrypt a text, then put this into a mysql database.
This works fine, however with long texts, the decrypted text becomes corrupted.
Personally I think this is due to the way mysql saves this text into the database, there are a lot of not alpha numeric characters in the encrypted text. But I am not sure about that.
Also I don't know which collation to use in mysql, right now I set it to *utf8_unicode_ci*, but still there is corruption of data.
A live example can be seen here: http://todolist.x10.mx
Username: example
Password: password
To view the corrupted data, click Download Backup.
Below the code, of course $encrypted is saved into the database. This code works fine without database.
<?php
$source = 'very long text';
$iv = "1234567812345678";
$pass = 'difficultpassphrase';
$method = 'aes-256-ofb';
$encrypted = openssl_encrypt ($source, $method, $pass, true, $iv);
echo $encrypted;
$decrypted = openssl_decrypt ($encrypted, $method, $pass, true, $iv);
echo $decrypted;
?>
Thank you in advance for your time and expertise.
To store encrypted content in binary form, you can't use a character type with encoding since it's very likely that the encoding "breaks" your data.
You should instead use BINARY or VARBINARY datatypes, they're made exactly for the purpose of storing binary data.
The alternative is to base64_encode the data before storing it in the character datatypes, and base64_decode the data when you've fetched it from the database. This will encode the data so that the encrypted data is possible to store in a varchar/char datatype (although it will make the data slightly longer, so beware of that)
I've seen this asked a few times, but not exactly how I'm going to ask it here... Hopefully this is ok with you guys.
Basically I have this script that works fine and will print my result without a hitch:
$algorithm = MCRYPT_BLOWFISH;
$mode = MCRYPT_MODE_CFB;
$iv = mcrypt_create_iv(mcrypt_get_iv_size($algorithm, $mode), MCRYPT_DEV_URANDOM);
$key = 'Wassup';
$data = 'I am a guy';
$enc_data = rtrim(mcrypt_encrypt($algorithm,$key,$data,$mode,$iv));
$plain_text = base64_encode($enc_data);
echo $plain_text . "\n";
// OUTPUTS: 6m3D5qSrfz3w6pKuuybs
$enc_data = base64_decode($plain_text);
$decoded = mcrypt_decrypt($algorithm,$key,$enc_data,$mode,$iv);
echo $decoded;
// OUTPUTS: I am a guy
This is perfect. NOW... instead of just instantly outputting what I put in, I'm trying to store that info in my database to be decrypted later.
I can see the encrypted string fine in my table row: 6m3D5qSrfz3w6pKuuybs. So, I'm sure it's going IN just fine..
and when I query to get it out it looks just the same,
but now when I decode and decrypt I get something like: ÝÄ/$ÍñËt05883700
The table field is set up as a VARCHAR (255) utf8_general_ci. Is this where the problem is?
Are you sure you are using the same initialization vector (IV) on encryption and decryption?
Note that you need to save the IV as well and use it when you are decrypting. Also don't use rtrim() on the ciphertext.
That being said, you could use a BINARY (or VARBINARY) field to store your ciphertext (and the IV), so you don't need to base64 encode it. It will save you 33% of storage.