我从客户端获得了一个提供的Key和IV,但是我正在使用的函数没有返回预期的结果。我不能发布密钥和IV,因为它们是敏感信息。我唯一不确定的是我连接的网络服务是.NET,我在php工作,你可以在下面看到我尝试过填充方法。有什么想法吗?
function encrypt($str, $key, $iv){
$block = mcrypt_get_block_size('rijndael_128', 'cbc');
$pad = $block - (strlen($str) % $block);
$str .= str_repeat(chr($pad), $pad);
return mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $str, MCRYPT_MODE_CBC, $iv);
}
答案 0 :(得分:-1)
在这里,诀窍是使用32个字符的密钥。这是用于php的原始AES 256加密方法。这使用随机IV和base 64编码将二进制数据存储为字符文本,很难说如何解密您拥有的内容而不查看它是如何加密的。也就是说,这是在php中进行AES256的正确方法。
//**************** Symmetric ****************//
function symEncode($decrypted, $key){
# show key size use either 16, 24 or 32 byte keys for AES-128, 192
# and 256 respectively
//$key_size = ini_get('mbstring.func_overload') ? mb_strlen($key , '8bit') : strlen($key);
// Build $iv and $iv_base64. We use a block size of 128 bits (AES compliant) and CBC mode. (Note: ECB mode is inadequate as IV is not used.)
$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC), MCRYPT_RAND);
if (strlen($iv_base64 = rtrim(base64_encode($iv), '=')) != 22) return false;
// Encrypt $decrypted and an MD5 of $decrypted using $key. MD5 is fine to use here because it's just to verify successful decryption.
$encrypted = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $decrypted . md5($decrypted . $key), MCRYPT_MODE_CBC, $iv));
// We're done!
return $iv_base64 . $encrypted;
}
要解码这个。
function symDecode($encrypted, $key){
// Retrieve $iv which is the first 22 characters plus ==, base64_decoded.
$iv = base64_decode(substr($encrypted, 0, 22) . '==');
// Remove $iv from $encrypted.
$encrypted = substr($encrypted, 22);
// Decrypt the data. rtrim won't corrupt the data because the last 32 characters are the md5 hash; thus any \0 character has to be padding.
$decrypted = rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, base64_decode($encrypted), MCRYPT_MODE_CBC, $iv), "\0\4");
// Retrieve $hash which is the last 32 characters of $decrypted.
$hash = substr($decrypted, -32);
// Remove the last 32 characters from $decrypted.
$decrypted = substr($decrypted, 0, -32);
// Integrity check. If this fails, either the data is corrupted, or the password/salt was incorrect.
if (md5($decrypted . $key) != $hash){
die( 'failed to decode data');
}
你看到了这个吗?
Php Decrypt a String from C# .NET RIJNDAEL 256
IN回复downvote
与任何MAC一样,它可用于同时验证两个数据 完整性和消息的身份验证。任何加密哈希 函数,如MD5或SHA-1,可用于计算a HMAC
此外(甲骨文攻击)
为防止此攻击,可以附加HMAC(基于哈希的消息 认证码)到密文。没有习惯的钥匙 生成HMAC,攻击者无法生成有效的 密文。由于在解密阶段之前检查HMAC, 攻击者不能做必要的比特,因此不能 发现明文。
那么,你在评论中对此有所了解吗? 你会如何改进它? (我看到的唯一方法是将键添加到我现在已经完成的md5哈希)
当然,我不是加密专家,但上面的代码总是使用相同的纯文本加密到不同的加密文本。
不要错误地认为最后32个字符是静态的,因为md5哈希(非随机)在解密整个消息之前不会暴露。
这需要IV和KEY。然后使用md5哈希以编程方式验证数据是否已成功进行UN加密,从而避免任何修改/篡改加密数据的尝试。
攻击者几乎没有办法猜测"附加IV的地方(这是在击败oracle攻击中描述的HMAC),因为它也是随机文本。实质上,他们需要访问代码甚至开始解密它。如果他们可以访问服务器文件系统,则会遇到更大的问题。
实质上,这是方案
[random IV] [ encrypted [md5 hash] ]
至于与上面的代码相比,这是一个不可能的命题,
我要求的。
一旦提供了那个,就可以验证你可以原生地从A中取出A,因为使用密码的加密性质总是不同的(如果它正确完成)。因此,仅从密文反向工程解决方案几乎是不可能的。而且我们甚至没有输入和密文生成的例子。正如我所提到的,没有看到它是如何被原生解密的,它充其量只是在猜测。
因此,我唯一能做的就是如何在PHP中使用AES加密/解密它?