PHP AES加密......不知道我在做什么
-
26-09-2019 - |
题
我不知道很多有关加密,但我能得到AES工作在PHP中......有点。这里有几个功能,我使用:
function aes_decrypt($val,$ky)
{
$key="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
for($a=0;$a<strlen($ky);$a++)
$key[$a%16]=chr(ord($key[$a%16]) ^ ord($ky[$a]));
$mode = MCRYPT_MODE_ECB;
$enc = MCRYPT_RIJNDAEL_128;
$dec = @mcrypt_decrypt($enc, $key, $val, $mode, @mcrypt_create_iv( @mcrypt_get_iv_size($enc, $mode), MCRYPT_RAND) );
return rtrim($dec,(( ord(substr($dec,strlen($dec)-1,1))>=0 and ord(substr($dec, strlen($dec)-1,1))<=16)? chr(ord( substr($dec,strlen($dec)-1,1))):null));
}
function aes_encrypt($val,$ky)
{
$key="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
for($a=0;$a<strlen($ky);$a++)
$key[$a%16]=chr(ord($key[$a%16]) ^ ord($ky[$a]));
$mode=MCRYPT_MODE_ECB;
$enc=MCRYPT_RIJNDAEL_128;
$val=str_pad($val, (16*(floor(strlen($val) / 16)+(strlen($val) % 16==0?2:1))), chr(16-(strlen($val) % 16)));
return mcrypt_encrypt($enc, $key, $val, $mode, mcrypt_create_iv( mcrypt_get_iv_size($enc, $mode), MCRYPT_RAND));
}
这些是略微从mcrypt的PHP文档页面上的评论改性。 (I从dev_urandom变为兰特,由于我上的窗口框,其中dev_urandom不可用。)
反正在该功能键我使用的定义如下:
define("PSK", pack("H*", "abcd7b5ca46e12345678a8161fdacee9"));
我把我的功能是这样的:
echo bin2hex(aes_encrypt("wootwootwootwootwootwootwoo", PSK));
现在,将所得的十六进制字符串的第一个16个字节(32位)都很好。接下来的16个字节不匹配的期望是什么。
请参阅,我张贴这个数据到外部web服务在于然后将其解密。我(不幸)不能给出一个测试情况下,我有没有发放我的加密密钥和数据。我对此非常抱歉,但我希望有人熟悉mcrypt的可以看看这个,告诉我什么,我做错了。
再次遗憾的是,缺乏一个坚实的试车情况,但我非常赞赏的任何帮助,您可以给!
编辑:看来我的供应商,我张贴到使用空IV。继鲁克的建议,我已经切换到CBC模式,并删除相关的键不必要的代码。这里是我的新功能:
function aes_decrypt($val,$key)
{
$mode = MCRYPT_MODE_CBC;
$enc = MCRYPT_RIJNDAEL_128;
$dec = @mcrypt_decrypt($enc, $key, $val, $mode, null);
return rtrim($dec,(( ord(substr($dec,strlen($dec)-1,1))>=0 and ord(substr($dec, strlen($dec)-1,1))<=16)? chr(ord( substr($dec,strlen($dec)-1,1))):null));
}
function aes_encrypt($val,$key)
{
$mode = MCRYPT_MODE_CBC;
$enc=MCRYPT_RIJNDAEL_128;
$val=str_pad($val, (16*(floor(strlen($val) / 16)+(strlen($val) % 16==0?2:1))), chr(16-(strlen($val) % 16)));
return mcrypt_encrypt($enc, $key, $val, $mode, null);
}
解决方案
很可能,这个加密服务使用像CBC操作的不同的块加密模式。如果空四正与CBC模式中使用,则第一区块(在此情况下16个字节)ECB和CBC的将产生相同的密文。 ECB模式不应该被任何人使用的任何理由。
下面是一个例子ECB模式加密的消息:
其他提示
我和我的一个大学,其中编码iPhone应用程序,并且其中利用上述方法来加密和解密数据。但是我们发现一个问题,当我被加密从他的iPhone读取的数据。在iPhone中使用PKCS7填充。上面的代码中添加额外的填充这会导致iPhone解密方法失败。我们修改了代码,以解决当前的问题:
public static function aes128Encrypt($key,$val)
{
$mode = MCRYPT_MODE_CBC;
$enc=MCRYPT_RIJNDAEL_128;
$blocksize= mcrypt_get_block_size($enc,$mode);
$stringLength = strlen($val);
$paddingLength =$blocksize-($stringLength%$blocksize);
$val=str_pad($val,$paddingLength+$stringLength,chr($paddingLength));
return base64_encode(mcrypt_encrypt($enc, $key, $val, $mode, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"));
}