PHP AES-256加密

时间:2014-11-07 04:55:21

标签: php encryption

我从客户端获得了一个提供的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);
}

1 个答案:

答案 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] ]

至于与上面的代码相比,这是一个不可能的命题,

  • 明文示例
  • B用于加密数据的确切代码/方法
  • C上面使用的加密代码/方法的输出
  • 虽然即使B就够了,但最好还是验证一下"方法"在完成所有工作之前,让它可以移植到PHP mcrypt。

我要求的。

一旦提供了那个,就可以验证你可以原生地从A中取出A,因为使用密码的加密性质总是不同的(如果它正确完成)。因此,仅从密文反向工程解决方案几乎是不可能的。而且我们甚至没有输入和密文生成的例子。正如我所提到的,没有看到它是如何被原生解密的,它充其量只是在猜测。

因此,我唯一能做的就是如何在PHP中使用AES加密/解密它?