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