How to avoid that "%2500" gets added to string after encryption? [duplicate] - php

Working with OAuth and encrypting the keys with the following function with a string which we'll call 'foo' (actually an OAuth token)
public function encrypt( $text )
{
// add end of text delimiter
$data = mcrypt_encrypt( MCRYPT_RIJNDAEL_128, $this->key, $text, MCRYPT_MODE_ECB, $this->iv );
return base64_encode( $data );
}
When I decrypt it using the inverse function, I end up with:
Function:
public function decrypt( $text )
{
$text = base64_decode( $text );
return mcrypt_decrypt( MCRYPT_RIJNDAEL_128, $this->key, $text, MCRYPT_MODE_ECB, $this->iv );
}
Result:
foo%00%00%00%00%00%00%00%00%00%00%00%00%00%00
Edit:
Looking at it a little more, I realized that it is actually URL encoding to %00, which means that my strings are somehow being padded by null characters? So I am currently using trim() to get rid of them, but I would like to understand why this is happening.

Rijndael is a block cypher, which means that it operates on chunks of data of a particular length (128 bits in this case). This means that if the length of the input text is not a multiple of the block size, it must be padded out to fit. In this case, the padding is zeros; there are a number of other possible padding schemes that could be used, but if you want them with PHP's mcrypt you'll have to apply them manually.

You can Fix it with this method to get rid of padding characters: In our case we are using Zend.
$filter = new Zend_Filter_Decrypt(array('adapter' => 'mcrypt'));
$filter->setVector($lpt->_seed);
str_replace("\x0", '', trim($filter->filter(base64_decode($textToDecrypt))));

MCRYPT_MODE_ECB means that you are using ECB, a block cipher mode of operation. Block ciphers can be handled either for block cipher modes of operation or for stream cipher modes of operation. Common block cipher modes are ECB and CBC, a common stream cipher mode is CTR, better known as counter mode operation.
MCRYPT_RIJNDAEL_128 is an implementation of AES. AES is the Rijndael cipher with a block size of 128 bits, and three possible key sizes, 128, 192 and 256 bits. So if you use a block cipher mode of encryption then you need to divide up the plain text is sizes of 128 bits - 16 bytes - each. Of course this leaves you with the question what to do when the last block is not 16 bytes.
PHP's mcrypt_encrypt more or less leaves this up to the user. It pads with 00 valued characters if the block is not full up to the block size. This is fine if the input is a string; you can simply trim off the 00 characters from the returned string. If the input is however binary data that ends with a 00 character than that character is lost (+ any other character that is taken from the start and end of the string of course). You can also send the length of the string encrypted together with the plaintext of course.
For a better scheme you only have to look at PKCS#7 padding. Multiple code snippets for implementing the padding can be found in the comments section of mcrypt_encrypt.
mcrypt_encrypt currently does not seem to support stream modes for AES, so that option is out if you want to keep with the PHP mcrypt library.

Related

Encrypt data with aes-256-cbc with openssl in php

I am trying to encrypt hexadecimal data with openssl aes-256-cbc in php language. My data length is 32 byte and key length is 32 byte and iv is 16 byte 0.
I used openssl_encrypt function to encrypt the hexadecimal data but function output so long I expected. I don't know where is my fault.
Here is the code below:
$plainData = "00A40800063D103D202F2400";
$encryptionMethod = "aes-256-cbc";
$encryptionKey = "395f426c0e5bd914375837483b791d80854dd9a19dd86fd189e94ccade60c5b8";
$iv = "0000000000000000";
$encryptedData = openssl_encrypt($plainData, $encryptionMethod, $encryptionKey, $iv);
Output: 6e6469763877536e534a4f677168716f67692f684a4166315767534951764f645a575044554f6f4162763333332f6c516d6a397635723566713259444f6e79586137586e366e4f476e7a46765a4b45302b4b4855676961786757556361373932766869584453385749726f3d
Expected output length is 32 byte but above output is 216 character string.
Where is the problem above code block?
The length is different in size because of so called padding. The padding used by default is PKCS#7 compatible padding. This padding is always added; this way the padding can be distinguished from possible (binary) plaintext.
If you already know that the ciphertext is always a multiple of the block size then you can use OPENSSL_NO_PADDING as option both during encryption and decryption; you will then be responsible for making sure that the plaintext is a multiple of the block size during encryption.
It is possible to use AES-CBC with an all zero IV, but remember that this leaks information about the plaintext: repeated plaintext blocks at the start of the plaintext message can be identified. The only way to reliably use an all zero IV is to make sure that the first plaintext block is never identical or to change the key on every call.
Also note that CBC mode is malleable - if the ciphertext or plaintext can be altered by an attacker the simple encryption mode you're describing is bound to have security issues.

mcrypt_decrypt adding null at the end of decrypted text

I used Rijndael algorithm to encrypt and decrypt my database password. I kept encoded password in another file. Here I reduced the code to get relevant :
$encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, PASSWORD_SALT, 'mypassword', MCRYPT_MODE_ECB);
$decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, PASSWORD_SALT, $encrypted, MCRYPT_MODE_ECB);
// !! The value of $decrypted is "mypassword " i.e. "mypasswordNULLNULLNULLNULLNULL"
'mypassword' is converted to 'mypassword' + 6xNULL. The decrypted code is containing null.
I wrote this code 1 year ago and everything was working fine. But now, when version of all technologies have changed, I am having problem.
It was always so.
According to documentation:
The data that will be decrypted with the given cipher and mode. If the size of the data is not n * blocksize, the data will be padded with '\0'.
So either you trim your data with \0, or you have to store the original length anywhere and then cut the padded 0 off.
Using the Rijndael-128 algorithm mcrypt_encrypt() will always return multiples of 16 bytes. If your plain text ist not an exact multiple of 16 bytes the data will be padded with zero bytes so it will be a multiple of 16.
Those zero Bytes will appear in the decrypted text as well. You have to remove those by using:
$decrypted = rtrim($decrypted, "\0");
Note 1: Rijndael is a block encryption algorithm which operates on block of a fixed size. This is why padding may be necessary.
Note 2: Encryption is only suitable for encoded input that never ends with value 00h (because of default zero padding). Taken from example code at http://php.net/manual/en/function.mcrypt-encrypt.php

Common PHP mcrypt_encrypt() code sometimes fails decryption

This code is from several websites, the source of which has mentioned SO as a source for help in its creation.
This is the uncompressed version, of which I changed the base64 encode and decode to hex2bin and bin2hex as I thought this was giving me problems when passing between webpages, but was because I was on occations getting trash data as the decryption result.
With either code, using the same key and different data, on occasions gives me trash data as the decryption result. It seems to be the data itself, as opposed to repetition, the data size may be between 30 - 80 characters.
The data is just a series of numbers and letters, all within the usual ASCII standard, no nulls, nothing beyond standard email address characters.
I'm using Ubuntu 14.04 LTS, with PHP 5.5.9-1ubuntu4.5 (Zend: 2.5.0)
Has anyone experienced this kind of problem?
EDIT: From reading more SO, apparently $iv should be the same for encrypt and at the time of decrypt, but if this is true why would it work most of the time anyway?
function mc_encrypt($encrypt, $mc_key) {
$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND);
$passcrypt = trim(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $mc_key, trim($encrypt), MCRYPT_MODE_ECB, $iv));
$encode = bin2hex($passcrypt);
return $encode;
}
function mc_decrypt($decrypt, $mc_key) {
$decoded = hex2bin($decrypt);
$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND);
$decrypted = trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $mc_key, trim($decoded), MCRYPT_MODE_ECB, $iv));
return $decrypted;
}
Rijndael is a symmetric block cipher. It operates on blocks and in this case, the blocks are 256-bit wide. The ciphertext is supposed to look random, but it isn't. Otherwise, it wouldn't be possible to reverse the encryption. Since this is ECB mode, there is no IV which randomizes the whole thing. And because of this every plaintext block combined with the key will result in the same ciphertext block. So the issue is reproducible only based on the same data.
Since the encryption is supposed to look random, it will happen that the first byte of the ciphertext will contain a whitespace (when shown as characters). trim removes 6 types of whitespace and will remove at least the first byte in those cases. So, the problem will happen in 6/256 of cases (~2%).
If for example the first byte is a space, then it will be removed. Now the first block doesn't have all the bytes and the block boundary for decryption is moved. So, the first byte from the next block is used as the last byte of the first block to decrypt the block. Since Rijndael is a block cipher, only garbage will come out. And this happens for all blocks.
Usually rtrim is used instead of trim to unpad the plaintext: rtrim(mcrypt_decrypt(...), '\0');. The trim of the ciphertext should be removed completely.
This isn't whole story, because the end of the encryption/decryption is trimmed which can break the result. It's best to actually use PKCS#7 padding by implementing it yourself and completely lose the *trim. Sadly php_mcrypt doesn't provide the PKCS#7/PKCS#5 padding.

Extra Characters Output From mcrypt_decrypt

I am in need of symmetric encryption and decryption in a pair of PHP scripts. I am using mcrypt_encrypt and crypt_decrypt. To test this, I have the following code:
$encrypted_token = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $ENCRYPTION_SECRET, $refresh_token, MCRYPT_MODE_ECB);
$encrypted_encoded_token=base64_encode($encrypted_token);
echo "\nEncrypted Token: " . $encrypted_encoded_token . "\n";
To test this, in the same PHP script I do the following:
$decoded_refresh_token = base64_decode($encrypted_encoded_token);
$decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $ENCRYPTION_SECRET, $decoded_refresh_token, MCRYPT_MODE_ECB);
echo "\nDecrypted Token After decrypt: " . $decrypted . "\n";
My input $refresh_token is a long string of characters that looks something like this (only longer):
AQCNKTZhaWTmUl3WvHOtlkv2Vc-Ybkl24D5Zp1lZPLBraTxrr-YQhErXrI2IWWEIWk5lnBc1k
The Decrypted Token After decrypt looks something like this:
AQCNKTZhaWTmUl3WvHOtlkv2Vc-Ybkl24D5Zp1lZPLBraTxrr-YQhErXrI2IWWEIWk5lnBc1k�������������������
My $ENCRYPTION_SECRET is 32 characters long. The base64_encode and decode are because I am json_encoding and decoding the token in a Post.
What am I doing wrong?
Those extra characters are indeed bytes valued zero. PHP's mcrypt uses 0..n - 1 bytes of zero padding, where n is the blocksize. In other words, if the plaintext is already a multiple of the blocksize then it doesn't pad. Otherwise it pads up to the block size.
Now you are using MCRYPT_RIJNDAEL_256 which is not AES, but Rijndael with a block size of 256 bits. So the number of bytes added are 0..31 bytes. If you view those as a string they get converted to question marks or removed, depending on what you view the string with. In the C-library of mcrypt that probably made more sense as zero terminates a null-terminated string.
Nowadays the ad-hoc standard is PKCS#7 padding, which adds 1..blocksize of padding bytes. If x is the number of padding bytes then x is also the value of the bytes added. PKCS#7 padding is deterministic, i.e. you can always unpad, no matter the value of the plaintext. Zero padding behaves largely the same way, unless the plaintext contains zero characters at the end. This is however never the case for printable strings (in ASCII, latin or UTF-8).
Finally, to remove the padding, simply perform rtrim(plaintext, "\0") and you'll get the original string.

AES encryption for storing data on cookie

I need to store the maximum chars as possible on a cookie having char string to store encrypted in AES.
cookie has about 4kb memory.
So i need to count how much chars i can store in a cookie encrypting in AES all these chars.
chars to store is an alphanumerical string.
EDIT: i can allow all the UTF-8 alphanumeric chars both in plaintext and in chipertext
THIS IS MY PIECE OF CODE
<?php
$Pass = "132ksjcngpt04938idjsk39urtokg";
$Clear = "123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123456789012345678901234567890123456789o";
$crypted = fnEncrypt($Clear, $Pass);
echo "Encrypred: ".$crypted."<br></br>";
$newClear = fnDecrypt($crypted, $Pass);
echo "Decrypred: ".$newClear."<br></br>";
function fnEncrypt($sValue, $sSecretKey)
{
return trim(
base64_encode(
mcrypt_encrypt(
MCRYPT_RIJNDAEL_128,
$sSecretKey, $sValue,
MCRYPT_MODE_ECB,
mcrypt_create_iv(
mcrypt_get_iv_size(
MCRYPT_RIJNDAEL_128,
MCRYPT_MODE_ECB
),
MCRYPT_RAND)
)
)
);
}
function fnDecrypt($sValue, $sSecretKey)
{
return trim(
mcrypt_decrypt(
MCRYPT_RIJNDAEL_128,
$sSecretKey,
base64_decode($sValue),
MCRYPT_MODE_ECB,
mcrypt_create_iv(
mcrypt_get_iv_size(
MCRYPT_RIJNDAEL_128,
MCRYPT_MODE_ECB
),
MCRYPT_RAND
)
)
);
}
?>
I TESTED AND THIS IS THE RESULT:
Encrypred: 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
Decrypred: 123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123hryd{}ls.-''ksllasllallallallallal:{}::{}jdhhfn123456789012345678901234567890123456789o
chiperText is compoused of 3040 utf-8 chars
encrypted is up to 4056 utf-8 chars
If you use an authenticated streaming mode, such as AES-GCM, the raw ciphertext size in bytes will be 32 bytes larger than the plaintext size. 16 of those are for a random IV, and 16 for the MAC.
Now you have the problem that arbitrary bytes aren't valid UTF-8, so you need some encoding to take care of that. Base64 is a popular variant, but it increases the size to 4/3 of the original size.
This means if your size limit is 4KiB, you'll be able to support plaintexts of up to 3040 bytes.
There are other more efficient encodings, but that gets more complicated, and you'll need to figure out which characters are valid (such as \0). I don't recommend that unless absolutely necessary.
Your code has plenty of mistakes:
You're using ECB, pretty much the worst of all modes
You need the same IV for encryption and decryption. So store it alongside the ciphertext. You don't notice it, since ECB doesn't use an IV.
You don't have authentication.
Your IV generation isn't good. Use MCRYPT_DEV_URANDOM instead of MCRYPT_RAND.
Correct me if I wrong but supposing you're using UTF-8 as alphanumerical character for your plain text, since AES works with 16 byte length blocks (that can be viewed as 16 alphanumerical character in this context), your plain text is at least padded with 15 byte (the worst scenario).
So, given n the length of your plain text, the resulting cipher text length can be inferred with:
(n + 16) - (n % 16)
Just my 2 cents.
Dario.

Categories