Related
I have acquired a public key from a service provider and i now want to encrypt a password.
I have tried to encrypt this way
$publicKey = file_get_contents('cert.cer');
//$plaintext = "Safaricom132!";
$plaintext = "safaricom323!";
openssl_public_encrypt($plaintext, $encrypted, $publicKey, OPENSSL_PKCS1_PADDING);
echo base64_encode($encrypted);
I get this result
k97YxoV0uS08ok0n99id8PPp9kfSdebhdHaVroTmGF16hR70+U30xSrsRgIaVvHrzu535oH7Mz2TxkgQktq4TmVnxIhWbwBYDlVfnNoAUaHAW/oOYbF6bRR+vCHvMAI8TrQLaMK8XhVMjHqr27pmoqEyzEYC0sop+rp2T81CcWFlyJDr57GHuSoeka8pHMFSsGGvU7S+K0ZZ7xNQGOUpvT8skDMo3u7RUjbDk466dEtR1SUWfYTwVcrBCAFWI9ElfzFzgrWSr+ECelbU7n4D9dJegt9HvPhI2Nnc2q0V7DvHdwO+lHt7tKlM9xbxCTewiFHWjn9+lCAzwqnorHwN3g==
Should i specify the cipher i want to use or is the key i have generated a validly encrypted text?>
You have specified a cipher. Your certificate undoubtedly contains an RSA public key - so only RSA encryption is possible using this certificate. And you've specified PKCS#1 padding, which determines the encryption scheme used for RSA encryption.
No doubt you've generated a validly encrypted text. However, the only way to be 100% sure is to decrypt said ciphertext with the private key (after base 64 decoding the ciphertext, of course). If that returns your plaintext message - "safari323!" - then you know that decryption succeeded.
Note that PKCS#1 is not as secure as it was once thought to be. The current best of breed is OAEP padding or RSA-KEM.
I got the following requirements for the encryption for the API i am currently trying to access:
PKCS7 padding method
CBC encryption mode
AES key size 256, block size 128
Everytime i submit to the API with the encryption, there seems to be something wrong with the API (unfortunately no error is produced).
$Data = "GOOD!";
$aesKey = "1234567812345678";
$EncryptedData = encrypt($aesKey,$Data);
$DecryptedData = decrypt($aesKey,$EncryptedData);
echo "Orignal Data : ". $Data;
echo "<br/>";
echo "After encryption = ". $EncryptedData;
echo "<br/>";
echo "After decryption = " .$DecryptedData;
function encrypt($aesKey, $dataToEncrypt) {
$output = false;
$iv = '{{{{{{{{{{{{{{{{';
$output = openssl_encrypt($dataToEncrypt, 'AES-128-CBC', $aesKey,
OPENSSL_RAW_DATA, $iv);
$output = base64_encode($output);
return $output;
}
function decrypt($aesKey, $dataTodecrypt) {
$output = false;
$iv = '{{{{{{{{{{{{{{{{';
$dataTodecrypt = base64_decode ($dataTodecrypt);
$dataTodecrypt = $output = openssl_decrypt($dataTodecrypt, 'AES-128-CBC',
$aesKey, OPENSSL_RAW_DATA, $iv);
return $output;
}
Questions:
What exactly is PKCS7 padding method and can be implemented with php?
AES 256 is fine but what exactly does block size mean?
What exactly does IV do?
AES 256 is fine but what exactly does block size mean?
AES has a fixed block size of 128 bit. A block cipher only works on one block of a specific size. A mode operation extends a block cipher with the ability to work on multiple blocks and a padding enables it to work on plaintexts that are not a multiple of the block size.
AES-128-CBC means AES with key size of 128 bit and the CBC mode of operation. If you want to use AES-256, then you need to tell OpenSSL that: AES-256-CBC. Additionally, you need to use a key that is actually 256 bit long. Your current key is only 128 bit long.
What exactly is PKCS7 padding method and can be implemented with php?
openssl_encrypt() already does PKCS#7 padding for you and openssl_decrypt() removes it for you.
What exactly does IV do?
A random IV randomizes the ciphertext which means that encrypting the same plaintext with the same key, but a different IV produces a different ciphertext which is indistinguishable from random noise or other the same encryption with a different IV. Wikipedia has a good description what this actually does.
Keep in mind that an IV must be randomly generated for each iteration. Otherwise, an attacker who observes only the ciphertext may discover that you encrypted the same plaintext multiple times.
Keep in mind that an AES key is supposed to be quite noisy with high entropy. "12345..." looks more like a password. If you want to use passwords, then you need to derive a key from that password. PBKDF2 is a good idea with a random salt and a lot of iterations.
What exactly is PKCS7 padding method and can be implemented with php?
I am not really certain 'padding' is the phrase you mean here. While the PKCS#7 format does rely on padding, the example you provide has absolutely nothing to do with asymmetric encryption and the ASN.1 format for the PKCS#7 messaging syntax mentioned.
AES 256 is fine but what exactly does block size mean?
Block size is the bit size an encryption cipher, like AES-256, operates on per permutation.
What exactly does IV do?
An IV is short for initialization vector or for some symmetric encryption cipher implementations it can also be referred to as an nonce.
Both are used to help strengthen the resulting cipher text. You can think of them as being similar to a salt for a non-reversible hashing algorithm.
You should avoid re-using the same IV.
In regards to your example; the documentation for openssl_encrypt() states the following function usage:
string openssl_encrypt ( string $data , string $method , string $password [, int $options = 0 [, string $iv = "" ]] )
Your encryption of the plain text looks accurate (while I would choose AES-256-GCM vs. AES-128-CBC as the algorithm, blocksize & mode):
$output = openssl_encrypt($dataToEncrypt, 'AES-128-CBC', $aesKey,
OPENSSL_RAW_DATA, $iv);
Without testing I am assuming you are getting a valid base64 encoded value.
The manual for the openssl_decrypt() method states the following usage:
string openssl_decrypt ( string $data , string $method , string $password [, int $options = 0 [, string $iv = "" ]] )
While technically your implementation is correct; I would suggest the following (note the double assignment to $dataTodecrypt = $output = openssl_decrypt()):
$output = openssl_decrypt(base64_decode($dataTodecrypt), 'AES-128-CBC', $aesKey, OPENSSL_RAW_DATA, $iv);
I have decided recently to use a more secure encrytion for my password. I have no problem encrypting my password, after calling mc_encrypt($encrypt) the method returns an encrypted password.
When doing decryption by calling mc_decrypt($decrypt), the method returns false. As you can see in the mc_decrypt($decrypt) method, there is an if statement near the bottom. I cannot get the if statement to pass. Does anyone know what I can change to get $calcmac!==$mac to return true? Thanks
<?php
class Encrypt {
public $encryptionKey = 'xxxxxxx';
public function __construct() {
define('ENCRYPTION_KEY', $this->encryptionKey);
}
// Encrypt Function
public function mc_encrypt($encrypt){
$encrypt = serialize($encrypt);
$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC), MCRYPT_DEV_URANDOM);
$key = pack('H*', $this->encryptionKey);
$mac = hash_hmac('sha256', $encrypt, substr(bin2hex($key), -32));
$passcrypt = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $encrypt.$mac, MCRYPT_MODE_CBC, $iv);
$encoded = base64_encode($passcrypt).'|'.base64_encode($iv);
return $encoded;
}
// Decrypt Function
public function mc_decrypt($decrypt){
$decrypt = explode('|', $decrypt);
$decoded = base64_decode($decrypt[0]);
$iv = base64_decode($decrypt[1]);
$key = pack('H*', $this->encryptionKey);
$decrypted = trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $decoded, MCRYPT_MODE_CBC, $iv));
$mac = substr($decrypted, -64);
$decrypted = substr($decrypted, 0, -64);
$calcmac = hash_hmac('sha256', $decrypted, substr(bin2hex($key), -32));
if($calcmac!==$mac){ return false; }
$decrypted = unserialize($decrypted);
return $decrypted;
}
}
?>
Sorry, encrypting passwords with a secret stored on the server
isn't secure: If an intruder breaks into your codebase, intruder can retrieve
each and any password using your codebase and the stored password
(somewhere in code or your persistent store).
OWASP, the Online Web Application Security Project, provides well prepared documents: Password Storage Cheat Sheet, Authentication Cheat Sheet and PHP Security Cheat Sheet. Have a look!
The way to go is a salted hash.
How to handle newly created passwords
If you create a new password, compute hash = HashFunction( password, salt ) with a random salt
Save hash and salt in your database along to the user's ID
How to verify password
Locate the userID's record in your database
retrieve hash and salt from the record
Based on the password, that user entered to log in, compute hash = HashFunction( enteredPassword, salt )
Finally, verify if the hash retrieved from store is identical to the one computed.
Why use a hash operation?
A hash operation is a so called trapdoor function: While you can compute the function easily, it's hard to compute the reverse function.
Corollary: It's easy to compute a password-hash from a password, but it's hard to compute the password from the password-hash.
PHP's hash functions
These days, PHP's PBKDF2 is first choice for password hashes [Wikipedia on PBKDF2].
If your PHP installation is too old, even salted hashes with md5() are better than two-encrypted password. But only in case definitely nothing else is available!
Sample of PBKDF2 usage
function getHashAndSaltFromString( $password ) {
// choose a sufficiently long number of iterations
// ... to make the operation COSTLY
$iterations = 1000;
// Generate a random IV using mcrypt_create_iv(),
// openssl_random_pseudo_bytes() or another suitable source of randomness
$salt = mcrypt_create_iv(16, MCRYPT_DEV_RANDOM);
$hash = hash_pbkdf2("sha256", $password, $salt, $iterations, 20);
return array( $hash, $salt );
}
Beautiful side effect of hash usage
Many websites do restrict the length of passwords to a certain length - quite likely due to the length of the underlying persistent storage [= length of field in a database table].
If you use the hash-based password storage technique, your users might use passwords of arbitrary length!
Since the hash is of constant length and you only persist password and
salt, the length restriction is superfluous. Support long passwords in your web-app!
At an extreme case, you could even allow users to upload a file - e.g. a picture of their home - as a credential [=password].
Side note on random sources in PHP's MCRYPT functions
Note, that PHP does provide two sources of randomness MCRYPT_DEV_RANDOM and MCRYPT_DEV_URANDOM.
MCRYPT_DEV_RANDOM gets its randomness from /dev/random
MCRYPT_DEV_URANDOM gets its randomness from /dev/urandom
/dev/urandom provides random data immediately and non-blocking each time you query it, /dev/random might block (take some time to return).
Therefore, at first sight, /dev/urandom and MCRYPT_DEV_URANDOM might be better suited for random number generation. In fact, it is not!
/dev/random might block request up to a point of time, at which sufficiently much entropy has been collected. Thus /dev/random and MCRYPT_DEV_RANDOM effectively collects randomness.
If you need to do strong crypto operations, use MCRYPT_DEV_RANDOM or
/dev/random.
You shouldn't rely on two-way encryption for passwords. If someone can get the cyphertext, they can usually also get the key to decrypt them.
Instead, you should use hashing or key derivation like blowfish or pbkdf2, those are one-way functions that are designed to be hard to crack.
Please, never ever encrypt passwords this way.
If you are using PHP >= 5.3.7, you should use the password_comp library which was written by guys involved in PHP and it utilizes BCRYPT which is the strongest algorithm available for PHP as of yet.
It's very simple and easy to use.
https://github.com/ircmaxell/password_compat
Hash the password simply
$hash = password_hash($password, PASSWORD_BCRYPT);
Verify the given password against the stored password hash
if (password_verify($password, $hash)) {
/* Valid */
} else {
/* Invalid */
}
Pretty simple stuff, like they say no need to rewrite was has already been written especially when it comes to security and written by the experts.
I did a series of research on this topic, but unfortunately I couldn't find a perfect way to encrypt and decrypt files in PHP. Which mean what I'm trying to do is find some way to encrypt & decrypt my items without worry of cracker knew my algorithm. If some algorithm that need to secrete & hide, it can't solve my problems while once the logic shared through anywhere, or they broke into my server and get the source file, then it should be some way to decrypt it using the same decryption algorithm. Previously I found several great posts on StackOverFlow website, but it still couldn't answer my question.
The best way to encrypt password of the world, from what I conclude through reading. Blowfish encryption. It's one way hashing algorithm with 1000's times iteration which make cracker need 7 years to decrypt by using the same specification GPU.
Obviously, this makes it impossible to decrypt while it's one-way hashing.
How do you use bcrypt for hashing passwords in PHP?
Why do salts make dictionary attacks 'impossible'?
The best way to encrypt and decrypt password in PHP, as this question quote as it is. Refer to what I found through the web, sha1 and md5 both are cracked & broken algorithm, even we change the algorithm from
$encrypted = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($key), $string, MCRYPT_MODE_CBC, md5(md5($key))));
To
$encrypted = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, sha1(md5($key)), $string, MCRYPT_MODE_CBC, sha1(md5(md5($key)))));
Are not it's just increasing the toughness to decrypt it but still crack-able while just time issue ?
Best way to use PHP to encrypt and decrypt passwords?
I'm thinking of using our server processor / harddisc GUID to generate the salt and encrypt the password.
It's still some stupid way to do while cracker got the access to the server and they can just use PHP to echo the GUID and do the decryption. Or if it works, a few years later my website will be in trouble. The reason is harddisc, processor never last forever. When the time my processor or harddisc down, it's a time when my website down and lost all the credential.
Update
Found this question which doing with blowfish for decryption in PHP. Is it solving the question of finding secured way to encrypt and hard to decrypt by others ?
How to decrypt using Blowfish algorithm in php?
Can anyone please suggest on how should I overcome this issue ? Thanks.
Checkout this well documented article A reversible password encryption routine for PHP, intended for those PHP developers who want a password encryption routine that is reversible.
Even though this class is intended for password encryption, you can use it for encryption/decryption of any text.
function encryption_class() {
$this->errors = array();
// Each of these two strings must contain the same characters, but in a different order.
// Use only printable characters from the ASCII table.
// Do not use single quote, double quote or backslash as these have special meanings in PHP.
// Each character can only appear once in each string.
$this->scramble1 = '! #$%&()*+,-./0123456789:;<=>?#ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~';
$this->scramble2 = 'f^jAE]okIOzU[2&q1{3`h5w_794p#6s8?BgP>dFV=m D<TcS%Ze|r:lGK/uCy.Jx)HiQ!#$~(;Lt-R}Ma,NvW+Ynb*0X';
if (strlen($this->scramble1) <> strlen($this->scramble2)) {
trigger_error('** SCRAMBLE1 is not same length as SCRAMBLE2 **', E_USER_ERROR);
} // if
$this->adj = 1.75; // this value is added to the rolling fudgefactors
$this->mod = 3; // if divisible by this the adjustment is made negative
}
Caution:
If you are using PHP version >= 5.3.3, then you have to change the class name from encryption_class to __construct
Reason:
As of PHP 5.3.3, methods with the same name as the last element of a namespaced class name will no longer be treated as constructor.
Usage:
$crypt = new encryption_class();
$crypt->setAdjustment(1.75); // 1st adjustment value (optional)
$crypt->setModulus(3); // 2nd adjustment value (optional)
/**
*
* #param string $key - Your encryption key
* #param string $sourceText - The source text to be encrypted
* #param integer $encLen - positive integer indicating the minimum length of encrypted text
* #return string - encrypted text
*/
$encrypt_result = $crypt->encrypt($key, $sourceText, $encLen);
/**
*
* #param string $key - Your encryption key (same used for encryption)
* #param string $encrypt_result - The text to be decrypted
* #return string - decrypted text
*/
$decrypt_result = $crypt->decrypt($key, $encrypt_result);
Update:
Above class is not intended for encrypting files, but you can!!!
base64_encode your source text (file contents)
for actual encryption, apply above enc/dec class over base64-encoded text
for decryption, apply above enc/dec class over actually encrypted text
base64_decode will give you the actual file contents (you can save a copy of file with this content)
I've encrypted an image, decrypted back and saved to a new file!!! checkout the code.
//class for encrypt/decrypt routines
require 'class.encryption.php';
//configuring your security levels
$key = 'This is my secret key; with symbols (#$^*&<?>/!#_+), cool eh?!!! :)';
$adjustment = 1.75;
$modulus = 2;
//customizing
$sourceFileName = 'source-image.png';
$destFileName = 'dest-image.png';
$minSpecifiedLength = 512;
//base64 encoding file contents, to get all characters in our range
//binary too!!!
$sourceText = base64_encode(file_get_contents($sourceFileName));
$crypt = new encryption_class();
$crypt->setAdjustment($adjustment); //optional
$crypt->setModulus($modulus); //optional
//encrypted text
$encrypt_result = $crypt->encrypt($key, $sourceText, $minSpecifiedLength);
//receive initial file contents after decryption
$decrypt_result = base64_decode($crypt->decrypt($key, $encrypt_result));
//save as new file!!!
file_put_contents($destFileName, $decrypt_result);
Bear in mind that, in order to crack passwords, a hacker would have to have access to the encrypted passwords in the first place. In order to do that they would have to compromise the server's security, which should be impossible if the site is coded correctly (proper escaping or prepared statements).
One of the strongest yet simplest forms of encryption is XOR, however it is entirely dependent on the key. If the key is the same length as the encoded text, then it is completely unbreakable without that key. Even having the key half the length of the text is extremely unlikely to be broken.
In the end, though, whatever method you choose is secured by your FTP/SSH/whatever password that allows you to access the server's files. If your own password is compromised, a hacker can see everything.
Your question leads to two different answers. It's an important difference, whether you need to decrypt the data later (like files), or if you can use a one way hash (for passwords).
One-Way-Hash
If you do not need to decrypt your data (passwords), you should use a hash function. This is safer, because even if an attacker has control over your server and your database, he should not be able to retrieve the original password. Since users often use their password for several websites, at least he doesn't gain access to other sites as well.
As you already stated, one of the most recommended hash functions today, is bcrypt. Despite it's origin in the blowfish algorithm, it is in fact a hash function (not encryption). Bcrypt was designed especially to hash passwords, and is therefore slow (needs computing time). It's recommended to use a well established library like phpass, and if you want to understand how to implement it, you can read this article, where i tried to explain the most important points.
Encryption
If you need to decrypt your data later (files), you cannot prevent, that an attacker with control over your server, can decrypt the files as well (after all the server has to be able to decrypt it). All adds up to the question of where to store the secret key. The only thing you can do, is to make it harder to get the key.
That means, if you store the key in a file, it should be outside the http root directory, so it can on no account be accessed from the internet. You could store it on a different server, so the attacker would need control over both servers, though then you face the problem of the secure communication between the servers. In every case, you can make theft harder, but you cannot prevent it completely.
Depending on your scenario, you could encrypt the files locally on your computer, and only store the encrypted files on the server. The server would not be able to decrypt the files on it's own then, so they are safe.
So you already know about salting and hashing, but you can also "stretch" your passwords, where instead of just hashing each password once, you hash it several thousand times. This will slow down brute force attacks and increase the lifespan of your hashing algorithm. Interestingly it works by intentionally slowing down your server...
What I would recommend is writing your own custom hash function. First, you add salt to the password, then you pick a hash algorithm (say sha512, or perhaps a newer algorithm that is designed to be inefficient for this very purpose) and hash it, say, 10,000 times, then store it in the database. And as you already know, when a user logs in, instead of reversing the hash, you simply run their input through the same algorithm and see if it matches.
The beauty of writing your own hash function is that when it comes time to update your hash algorithm because the old one has become vulnerable to brute force attacks, all you have to do is add to your hash function, taking the result of the old hash algorithm, re-salting it, and hashing it again using your new algorithm. You can use whatever hash algorithm is considered secure at the time. Then, you can simply re-hash every password already stored in your database with the new part of your hash function, thus ensuring backwards compatibility. Depending on how many users you have and how fast your server is, it might only take a couple of seconds to perform this update.
There is still a vulnerability, however. If a hacker has an old copy of your database and cracks it, he still knows the passwords of any users who haven't changed their passwords yet. The only way around this is to require your users to occasionally change their passwords, which may or may not be suitable for your site depending on the nature of the information it contains. Some security professionals suggest that users only change their passwords if they are compromised because if the system makes it too difficult to manage passwords, they will begin doing insecure things like keeping their passwords under their keyboards, which for some organizations is a bigger threat than having users that never change their passwords. If your website is a forum or review site or something of that nature, you should consider how much users have to lose by having their account hacked, how easy it is to restore their data to the way it was before it was hacked, and whether they will consider your site worth updating their password for if your password policy is too annoying.
One possible hash function:
function the_awesomest_hash($password)
{
$salt1 = "awesomesalt!";
$password = $salt1 . $password;
for($i = 0; $i < 10000; $i++)
{
$password = hash('sha512', $password);
}
// Some time has passed, and you have added to your hash function
$salt2 = "niftysalt!";
$password = $salt2 . $password;
for($i = 0; $i < 10000; $i++)
{
$password = hash('futuresuperhash1024', $password);
}
return $password;
}
Now, in order to update all the passwords already in your database, you would run them through this function:
function update_hash($password)
{
// This is the last part of your the_awesomest_hash() function
$salt2 = "niftysalt!";
$password = $salt2 . $password;
for($i = 0; $i < 10000; $i++)
{
$password = hash('futuresuperhash1024', $password);
}
return $password;
}
I like to write my own hash functions because it's easier to keep track of what exactly is happening for when it comes time to update them.
After some study of PHP, particularly the random number generation, the only way to securely encrypt with PHP is by using an OpenSSL wrapper. Especially the creators of mcrypt are a bunch of morons, just look at the example of not how to perform cryptography in their sample:
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$key = "This is a very secret key";
$text = "Meet me at 11 o'clock behind the monument.";
echo strlen($text) . "\n";
$crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_ECB, $iv);
echo strlen($crypttext) . "\n";
Note that by default MCRYPT_RAND is not seeded well. Furthermore, there is at least about 5 mistakes in above code alone, and they won't fix it.
[EDIT] See below for an ammended sample. Note that this sample is not very safe either (as explained above). Furthermore normally you should not encrypt passwords...
# the key should be random binary, use scrypt, bcrypt or PBKDF2 to convert a string into a key
# key is specified using hexadecimals
$key = pack('H*', "bcb04b7e103a0cd8b54763051cef08bc55abe029fdebae5e1d417e2ffb2a00a3");
echo "Key size (in bits): " . $key_size * 8 . "\n";
$plaintext = "This string was AES-256 / CBC / ZeroBytePadding encrypted.";
echo "Plain text: " . $plain_text . "\n";
$ciphertext_base64 = encryptText($key, $plaintext);
echo $ciphertext_base64 . "\n";
function encryptText(string $key_hex, string $plaintext) {
# --- ENCRYPTION ---
# show key size use either 16, 24 or 32 byte keys for AES-128, 192 and 256 respectively
$key_size = strlen($key);
# create a random IV to use with CBC encoding
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
# use an explicit encoding for the plain text
$plaintext_utf8 = utf8_encode($plaintext);
# creates a cipher text compatible with AES (Rijndael block size = 128) to keep the text confidential
# only suitable for encoded input that never ends with value 00h (because of default zero padding)
$ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $plaintext_utf8, MCRYPT_MODE_CBC, $iv);
# prepend the IV for it to be available for decryption
$ciphertext = $iv . $ciphertext;
# encode the resulting cipher text so it can be represented by a string
$ciphertext_base64 = base64_encode($ciphertext);
return $ciphertext_base64;
}
# === WARNING ===
# Resulting cipher text has no integrity or authenticity added
# and is not protected against padding oracle attacks.
# --- DECRYPTION ---
$ciphertext_dec = base64_decode($ciphertext_base64);
# retrieves the IV, iv_size should be created using mcrypt_get_iv_size()
$iv_dec = substr($ciphertext_dec, 0, $iv_size);
# retrieves the cipher text (everything except the $iv_size in the front)
$ciphertext_dec = substr($ciphertext_dec, $iv_size);
# may remove 00h valued characters from end of plain text
$plaintext_utf8_dec = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $ciphertext_dec, MCRYPT_MODE_CBC, $iv_dec);
echo $plaintext_utf8_dec . "\n";
So far i know the best way to save password is with salted hash like used in joomla. You can also add extra keys to md5 hash along with traditional base64.I wrote a script like that sometime ago, tried to find it but can't.
Joomla uses salted md5 passwords. Take the hashed password you gave: 30590cccd0c7fd813ffc724591aea603:WDmIt53GwY2X7TvMqDXaMWJ1mrdZ1sKb
If your password was say 'password', then:
md5('passwordWDmIt53GwY2X7TvMqDXaMWJ1mrdZ1sKb') = 30590cccd0c7fd813ffc724591aea603
So, take your password. Generate a random 32 character string. Compute the md5 of the password concatenated with the random string. Store the md5 result plus a : plus the random 32 character string in the database.
i have made a login and register page. but my passwords aren't encrypted yet. people told me that's a bad idea and that i should encrypt them. so i have been searching around on how to encrypt and decrypt my passwords. i have found an example on how to encrypt my passwords but i do not know how to decrypt it again for my login page. here is my encrypt code:
$key = "some random security key";
$input = $password;
$td = mcrypt_module_open('tripledes', '', 'ecb', '');
$iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
mcrypt_generic_init($td, $key, $iv);
$password = mcrypt_generic($td, $input);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
so my question is: can someone tell me what codes i need to decrypt the strings i get from the code above.
You can encrypt and decrypt stuff like this:
//this is some config for a good security level of mcrypt
define('SAFETY_CIPHER', MCRYPT_RIJNDAEL_256);
define('SAFETY_MODE', MCRYPT_MODE_CFB);
//this has to be defined somewhere in the application.
define('APPLICATION_WIDE_PASSPHRASE', 'put-something-secure-here');
define('ENCRYPTION_DIVIDER_TOKEN', '$$');
//some "example" data as if provided by the user
$password = 'this-is-your-data-you-need-to-encrypt';
//this key is then cut to the maximum key length
$key = substr(md5(APPLICATION_WIDE_PASSPHRASE), 0, mcrypt_get_key_size(SAFETY_CIPHER, SAFETY_MODE));
//this is needed to initialize the mcrypt algorythm
$initVector = mcrypt_create_iv(mcrypt_get_iv_size(SAFETY_CIPHER, SAFETY_MODE), MCRYPT_RAND);
//encrypt the password
$encrypted = mcrypt_encrypt(SAFETY_CIPHER, $key, $password, SAFETY_MODE, $initVector);
//show it (store it in db in this form
echo base64_encode($initVector) . ENCRYPTION_DIVIDER_TOKEN . base64_encode($encrypted) . '<br/>';
//decrypt an show it again
echo mcrypt_decrypt(SAFETY_CIPHER, $key, $encrypted, SAFETY_MODE, $initVector) . '<br/>';
But as stated before, passwords should not be recoverable from their hashed representation, so don't do this for passwords!
I see you're a bit confused with how this works. Read this article and you'll come to know all about encryption, decryption, hashing and their use in a login system.
http://net.tutsplus.com/tutorials/php/understanding-hash-functions-and-keeping-passwords-safe/
So basically, you hash a password into a hexadecimal string on registration and store it in the database. Each time the user wants to login you take his current i/p password, hash that and store it in a variable like $temp.
Now, you retrieve the original password's hash from the server and simple compare the two hashes.
...if they're same then access granted!
The many reasons you don't want to keep encrypting and decrypting a password are as follows:
When being passed to the server the user entered password is in plain
text or can be easily stolen/sniffed.
The server has to compute the process of decrypting the password stored in the database each time it is required, as opposed to
hashing where we just do a logical compare.
If the file containing the encyption algorithm is compromised w/ the database, all passwords are lost in plain text. As users may use
same passwords on multiple sites, the threat is extended.
You should not try to decrypt passwords just compair the hashed passwords.
By the way if you do that in the right way it is impossible to restore the original password. You should also add a so called salt to make the password more complex.