I have the following code that creates an encryption in PHP:
$password = "helloworld";
$passwordupper = strtoupper($password);
$passwordencode = mb_convert_encoding($passwordupper, 'UTF-16LE');
$passwordsha1 = hash("SHA1", $passwordencode);
$passwordbase64 = base64_encode($passwordsha1);
The instructions I have from the system I'm trying to connect to states:
The encoding process for passwords is: first convert to uppercase, then Unicode it in little-endian UTF 16, then SHA1 it then base64 encode it.
I think I'm doing something wrong in my code. Any ideas?
Answer solved by Marc B above in comments:
sha1 hash can either be raw binary, or a base64-encoded string to
begin with. e.g. $raw = sha1($string, true) v.s. $encoded =
sha1($string). you'd better try both variants, because you may be
double-base64-encoding.
Related
I need to send a password that's RSA encrypted with a public key (along with some other data). Here are the exact instructions from the documentation for the password:
Encode password in Base64 and ensure UTF-8 encoding
Encrypt password with RSA with provided public key, no block mode, and PKCS1Padding
Encode resulting encryption in Base64 with ensured UTF-8 encoding
Here's the code I'm using that to me seems correct:
function encryptPassword($pass) {
$pass = base64_encode($pass);
$fp = fopen("./cert.crt", "r");
$publicKey = fread($fp, 8192);
fclose($fp);
openssl_get_publickey($publicKey);
openssl_public_encrypt($pass, $cryptedText, $publicKey, OPENSSL_PKCS1_PADDING);
return base64_encode(utf8_encode($cryptedText));
}
I'm getting an error on the other side saying the password can't be decoded. Support from them is basically non-existent other than the error message, and them saying everything is correct on their side. My question is, am I sending what they're asking for according to the documentation?
Thanks in advance!
No, you've taken Base64 with ensured UTF-8 encoding too literally. utf8_encode transforms one textual encoding into another, but $cryptedText is not textual. It is a binary string, so you lose some characters during encoding. Simply remove it, because Base64 gives you already a textual representation of the binary data:
return base64_encode($cryptedText);
Additionally, you probably wanted to pass the public key resource into the encryption function:
$key_resource = openssl_get_publickey($publicKey);
openssl_public_encrypt($pass, $cryptedText, $key_resource, OPENSSL_PKCS1_PADDING);
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.
I need to do this with php encryption method.
turkey 3d a bank payment module in the code for the example given to me in this way encryption.
could you help me translate this into php code?
SHA1 sha1 = new SHA1CryptoServiceProvider();
byte[] notHashedBytes = System.Text.Encoding.ASCII.GetBytes(notHashedStr);
byte[] hashedByte = sha1.ComputeHash(notHashedBytes);
string hashedStr = System.Convert.ToBase64String(hashedByte);
return hashedStr;
I know nothing about .Net but from what I gathered in this page seems like the PHP equivalent is just:
$hashedStr = base64_encode(sha1($notHashedStr, true));
You need to encode the raw binary format and not the hexadecimal representation.
Is there a programmatic way to build htpasswd files, without depending on OS specific functions (i.e. exec(), passthru())?
.httpasswd files are just text files with a specific format depending on the hash function specified. If you are using MD5 they look like this:
foo:$apr1$y1cXxW5l$3vapv2yyCXaYz8zGoXj241
That's the login, a colon, ,$apr1$, the salt and 1000 times md5 encoded as base64. If you select SHA1 they look like this:
foo:{SHA}BW6v589SIg3i3zaEW47RcMZ+I+M=
That's the login, a colon, the string {SHA} and the SHA1 hash encoded with base64.
If your language has an implementation of either MD5 or SHA1 and base64 you can just create the file like this:
<?php
$login = 'foo';
$pass = 'pass';
$hash = base64_encode(sha1($pass, true));
$contents = $login . ':{SHA}' . $hash;
file_put_contents('.htpasswd', $contents);
?>
Here's more information on the format:
http://httpd.apache.org/docs/2.2/misc/password_encryptions.html
From what it says on the PHP website, you can use crypt() in the following method:
<?php
// Set the password & username
$username = 'user';
$password = 'mypassword';
// Get the hash, letting the salt be automatically generated
$hash = crypt($password);
// write to a file
file_set_contents('.htpasswd', $username ':' . $contents);
?>
Part of this example can be found: http://ca3.php.net/crypt
This will of course overwrite the entire existing file, so you'll want to do some kind of concatination.
I'm not 100% sure this will work, but I'm pretty sure.
Trac ships with a Python replacement for htpasswd, which I'm sure you could port to your language of choice: htpasswd.py.