我对这段代码的问题很少:
<?php
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$key = "This is a very secret key";
$text = file_get_contents('path/to/your/file');
echo strlen($text) . "\n";
$crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_ECB, $iv);
file_put_contents('path/to/your/file', $crypttext);
?>
Run Code Online (Sandbox Code Playgroud)
它加密文件很好,但它最后添加了额外的空值,所以如果我加密:
a test string is this one
and here is a new line
Run Code Online (Sandbox Code Playgroud)
一旦解密成为:
a test string is this one
and here is a new line 000000000000000
Run Code Online (Sandbox Code Playgroud)
这是怎么回事?
二,MCRYPT_RIJNDAEL_256兼容AES-128吗?
最后,我如何让另一方解密我加密的文件?他们需要知道使用了哪种加密,我不知道该告诉他们什么.
我要解释的大部分内容都可以从@ircmaxwell的优秀幻灯片中找到:密码学平均开发者,你应该立即查看.我将重申他的一个要点:避免编写处理加密/解密的代码.除非你了解所有因素,否则你可能会感染它.
的高级加密标准由国家标准与技术综合研究所创建.NIST 从竞争激烈的密码专家库中选择了Rijandael密码.
密钥大小是指用于加密/解密的秘密长度.256位密钥是32字节,大约32个字符.
块大小是块密码(即所有AES候选者)的属性,它在密码处理期间将数据分块为特定大小.
模式是一个重要的元素.
无论ECB和CBC模式触摸板您明文成块的大小.如果您使用128位块大小加密1字节数据,则将获得15个空字节.填充打开了填充oracle攻击的可能性.
除了填充之外,ECB不会使用初始化向量(IV),这会使您面临潜在的漏洞:更喜欢CBC或CFB模式.
您可以通过使用不需要填充的CFB模式 来避免这两个问题,因此不需要进行解密后修整.
在创建IV时,您需要一个加密的随机源:MCRYPT_RAND不够随机 - MCRYPT_DEV_RANDOM或者MCRYPT_DEV_URANDOM是首选.
$iv_size = mcrypt_get_iv_size(
MCRYPT_RIJNDAEL_128,
MCRYPT_MODE_CFB
);
$iv = mcrypt_create_iv(
$iv_size,
MCRYPT_DEV_URANDOM
);
Run Code Online (Sandbox Code Playgroud)
为了解密你的朋友需要知道:
MCRYPT_RIJNDAEL_128MCRYPT_MODE_CFB只有关键需要保密.根据您的传输方法,您应考虑实施数据完整性检查,以确保密文数据未被篡改.再次,请参阅@ircmaxwell的优秀幻灯片:平均开发人员的加密技术,以获取使用创建HMAC指纹的示例hash_hmac().
很明显,所有这些运动部件的维护都很复杂.小心翼翼.
Mcrypt为您提供其他密码选项.有些像DES一样不推荐.其他人是AES的候选人,如Blowfish,TwoFish和Serpent.Rijandael是经过验证的经过验证的密码,值得推荐.