Hello, I'm having some issues getting my encrypted output in C++ to decrypt
in PHP.
The C++ code I am using already functions fine (discussed here in the past).
int xxz568::AESEncrypt(std::string key, std::string input, std::string
&output, unsigned int PBKDFiterations) {
std::string hashedKey = whirlpool(key);
AutoSeededX917RNG rng;
SecByteBlock iv(AES::BLOCKSIZE);
rng.GenerateBlock(iv,iv.size());
// See NIST SP 800-132 for detailed recommendations on length, generation
and
// format of the salt. This test program will just generate a random one.
That
// might not be sufficient for every application.
SecByteBlock pwsalt(AES::DEFAULT_KEYLENGTH);
rng.GenerateBlock(pwsalt,pwsalt.size());
SecByteBlock derivedkey(AES::DEFAULT_KEYLENGTH);
PKCS5_PBKDF2_HMAC pbkdf;
pbkdf.DeriveKey(
// buffer that holds the derived key
derivedkey, derivedkey.size(),
// purpose byte. unused by this PBKDF implementation.
0x00,
// password bytes. careful to be consistent with encoding...
(byte *) hashedKey.data(), hashedKey.size(),
// salt bytes
pwsalt, pwsalt.size(),
// iteration count. See SP 800-132 for details. You want this as
large
as you can tolerate.
// make sure to use the same iteration count on both sides...
PBKDFiterations
);
string ciphertext;
CBC_Mode::Encryption aesencryption(derivedkey,derivedkey.size(),iv);
// encrypt message using key derived above, storing the hex encoded
result into ciphertext
StringSource encryptor(input, true,
new StreamTransformationFilter(aesencryption, new HexEncoder( new
StringSink(ciphertext), false))
);
std::string hexsalt, hexiv;
ArraySource saltEncoder(pwsalt,pwsalt.size(), true, new HexEncoder(new
StringSink(hexsalt), false));
ArraySource ivEncoder(iv,iv.size(), true, new HexEncoder(new
StringSink(hexiv), false));
output.assign(hexsalt);
output.append(hexiv);
output.append(ciphertext);
//
return 1;
}
int xxz568::AESDecrypt(std::string key, std::string input, std::string
&output, unsigned int PBKDFiterations) {
std::string hashedKey = whirlpool(key);
std::string saltPull, ivPull, cipherPull, store;
store.assign(input);
saltPull.assign(store.substr(0, 32));
store.assign(store.substr(32, store.length()));
ivPull.assign(store.substr(0, 32));
store.assign(store.substr(32, store.length()));
cipherPull.assign(store.substr(0, store.length()));
// now recover the plain text given the password, salt, IV and ciphertext
PKCS5_PBKDF2_HMAC pbkdf;
SecByteBlock recoveredkey(AES::DEFAULT_KEYLENGTH);
SecByteBlock recoveredsalt(AES::DEFAULT_KEYLENGTH);
StringSource saltDecoder(saltPull,true,new HexDecoder(new
ArraySink(recoveredsalt, recoveredsalt.size())));
pbkdf.DeriveKey(recoveredkey, recoveredkey.size(), 0x00, (byte *)
hashedKey.data(), hashedKey.size(),
recoveredsalt, recoveredsalt.size(), PBKDFiterations);
SecByteBlock recoverediv(AES::BLOCKSIZE);
StringSource ivDecoder(ivPull,true,new HexDecoder(new
ArraySink(recoverediv, recoverediv.size())));
try {
CBC_Mode::Decryption aesdecryption(recoveredkey, recoveredkey.size(),
recoverediv);
StringSource decryptor(cipherPull, true, new HexDecoder(
new StreamTransformationFilter(aesdecryption, new
StringSink(output))
));
}
catch(CryptoPP::Exception e) {
output = "Decryption Error: ";
output.append(e.GetWhat());
}
return 1;
}
However, when I try to decrypt a message generated using the following PHP
code:
<?php
error_reporting(0);
function pbkdf2($p, $s, $c, $dk_len, $algo = 'sha256') {
// experimentally determine h_len for the algorithm in question
static $lengths;
if (!isset($lengths[$algo])) { $lengths[$algo] = strlen(hash($algo,
null, true)); }
$h_len = $lengths[$algo];
if ($dk_len > (pow(2, 32) - 1) * $h_len) {
return false; // derived key is too long
} else {
$l = ceil($dk_len / $h_len); // number of derived key blocks to
compute
$t = null;
for ($i = 1; $i <= $l; $i++) {
$f = $u = hash_hmac($algo, $s . pack('N', $i), $p, true); //
first iterate
for ($j = 1; $j < $c; $j++) {
$f ^= ($u = hash_hmac($algo, $u, $p, true)); // xor each
iterate
}
$t .= $f; // concatenate blocks of the derived key
}
return substr($t, 0, $dk_len); // return the derived key of correct
length
}
}
//hex to binary (ASCII)
function hex2bin($data) {
$len = strlen($data);
for($i=0;$i<$len;$i+=2) {
$newdata .= pack("C",hexdec(substr($data,$i,2)));
}
return $newdata;
}
function addpadding($string, $blocksize = 32){
$len = strlen($string);
$pad = $blocksize - ($len % $blocksize);
$string .= str_repeat(chr($pad), $pad);
return $string;
}
function strippadding($string){
$slast = ord(substr($string, -1));
$slastc = chr($slast);
$pcheck = substr($string, -$slast);
if(preg_match("/$slastc{".$slast."}/", $string)){
$string = substr($string, 0, strlen($string)-$slast);
return $string;
} else {
return false;
}
}
// AES encryption as used in xxz568
define("CIPHER", MCRYPT_RIJNDAEL_256);
function AESEncrypt($key, $input, $pbkdf_iter) {
$hashedkey = hash('whirlpool', $key);
$iv_size = mcrypt_get_iv_size(CIPHER, MCRYPT_MODE_CBC);
$iv = mcrypt_create_iv(16, MCRYPT_RAND);
$salt = mcrypt_create_iv(16, MCRYPT_RAND);
//echo "IV: ". $iv ."
Salt: ". $salt;
$keyDerived = pbkdf2($hashedkey, $salt, $pbkdf_iter, 16);
//$e = openssl_encrypt($input, 'aes-256-cbc', $keyDerived, true, $iv);
$e = mcrypt_encrypt(CIPHER, $keyDerived, addpadding($input),
MCRYPT_MODE_CBC, $iv);
// convert to hex
$encryptedHex = bin2hex($e);
$final = bin2hex($salt).bin2hex($iv).$encryptedHex;
//echo "
ENC: ".$encryptedHex."
Outputted: ".$final."
DERKEY: ".$keyDerived."
HEXSALT: ".bin2hex($salt)."
HEXIV: ".bin2hex($iv)."
";
return $final;
}
// AES decryption as used in xxz568
function AESDecrypt($key, $input, $pbkdf_iter) {
$hashedkey = hash('whirlpool', $key);
$iv_size = mcrypt_get_iv_size(CIPHER, MCRYPT_MODE_CBC);
$store = $input;
$salt = subStr($store, 0, $iv_size);
$store = subStr($store, $iv_size, strlen($store));
$iv = subStr($store, 0, $iv_size);
$store_f = subStr($store, $iv_size, strlen($store));
$keyDerived = pbkdf2($hashedkey, hex2bin($salt), $pbkdf_iter, 16);
$d = strippadding(mcrypt_decrypt(CIPHER, $keyDerived, hex2bin($store_f),
MCRYPT_MODE_CBC, hex2bin($iv)));
return $d;
}
?>
It gives me this error: Decryption Error: StreamTransformationFilter:
invalid PKCS #7 block padding found.
I have tried using 32 instead of 16 on the PHP side, but then the message
size becomes larger than possible to match (same error message). Any idea
what the problem is here?
--
View this message in context:
http://old.nabble.com/Crypto%2B%2B-AES-with-PHP-tp32171615p32171615.html
Sent from the Crypto++ Users mailing list archive at Nabble.com.
--
You received this message because you are subscribed to the "Crypto++ Users"
Google Group.
To unsubscribe, send an email to [email protected].
More information about Crypto++ and this group is available at
http://www.cryptopp.com.