php - How to add/remove PKCS7 padding from an AES encrypted string? -
i'm trying encrypt/decrypt string using 128 bit aes encryption (ecb). want know how can add/remove pkcs7 padding it. seems mcrypt extension can take care of encryption/decryption, padding has added/removed manually.
any ideas?
let's see. pkcs #7 described in rfc 5652 (cryptographic message syntax).
the padding scheme given in section 6.3. content-encryption process. says: append many bytes needed fill given block size (but @ least one), , each of them should have padding length value.
thus, looking @ last decrypted byte know how many bytes strip off. (one check have same value.)
i give pair of php functions this, php bit rusty. either (then feel free edit answer add in), or have @ user-contributed notes mcrypt documentation - quite of them padding , provide implementation of pkcs #7 padding.
so, let's on first note there in detail:
<?php function encrypt($str, $key) { $block = mcrypt_get_block_size('des', 'ecb');
this gets block size of used algorithm. in case, use aes
or rijndael_128
instead of des
, suppose (i didn't test it). (instead, take 16
here aes, instead of invoking function.)
$pad = $block - (strlen($str) % $block);
this calculates padding size. strlen($str)
length of data (in bytes), % $block
gives remainder modulo $block
, i.e. number of data bytes in last block. $block - ...
gives number of bytes needed fill last block (this number between 1
, $block
, inclusive).
$str .= str_repeat(chr($pad), $pad);
str_repeat
produces string consisting of repetition of same string, here repetition of character given by $pad
, $pad
times, i.e. string of length $pad
, filled $pad
. $str .= ...
appends padding string original data.
return mcrypt_encrypt(mcrypt_des, $key, $str, mcrypt_mode_ecb);
here encryption itself. use mcrypt_rijndael_128
instead of mcrypt_des
.
}
now other direction:
function decrypt($str, $key) { $str = mcrypt_decrypt(mcrypt_des, $key, $str, mcrypt_mode_ecb);
the decryption. (you of course change algorithm, above). $str decrypted string, including padding.
$block = mcrypt_get_block_size('des', 'ecb');
this again block size. (see above.)
$pad = ord($str[($len = strlen($str)) - 1]);
this looks bit strange. better write in multiple steps:
$len = strlen($str); $pad = ord($str[$len-1]);
$len
length of padded string, , $str[$len - 1]
last character of string. ord
converts number. $pad
number used fill value padding, , padding length.
return substr($str, 0, strlen($str) - $pad);
so cut off last $pad
bytes string. (instead of strlen($str)
write $len
here: substr($str, 0, $len - $pad)
.).
} ?>
note instead of using substr($str, $len - $pad)
, 1 can write substr($str, -$pad)
, substr
function in php has special-handling negative operands/arguments, count end of string. (i don't know if more or less efficient getting length first , and calculating index manually.)
as said before , noted in comment rossum, instead of stripping off padding done here, should check correct - i.e. @ substr($str, $len - $pad)
, , check bytes chr($pad)
. serves slight check against corruption (although check more effective if use chaining mode instead of ecb, , not replacement real mac).
(and still, tell client should think changing more secure mode ecb.)
Comments
Post a Comment