【问题标题】:Picking encryption cipher for mcrypt为 mcrypt 选择加密密码
【发布时间】:2011-05-06 22:09:03
【问题描述】:

我对这段代码有几个问题:

<?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);    
?> 

它可以很好地加密文件,但是它在最后添加了额外的空值,所以如果我加密:

 a test string is this one
    and here is a new line 

一旦解密就变成:

a test string is this one
    and here is a new line 000000000000000

发生了什么事?

第二,MCRYPT_RIJNDAEL_256AES-128兼容吗?

最后,我如何让另一方解密我加密的文件?他们需要知道使用了哪种加密,我不知道该告诉他们什么。

【问题讨论】:

  • 我只能提供它使用 RIJNDAEL_256
  • 如何将其更改为 AES 128?

标签: php encryption


【解决方案1】:

MCRYPT_RIJNDAEL_128 相当于 mcrypt 中的 AES-128。这记录在MCRYPT_RIJNDAEL_128 下:http://mcrypt.sourceforge.net/

【讨论】:

    【解决方案2】:

    MCRYPT_RIJNDAEL_128 是 AES-128,MCRYPT_RIJNDAEL_256 是 AES-256 - just another name

    [...]该标准包括三个块 密码、AES-128、AES-192 和 AES-256, 从更大的收藏中采用 最初以 Rijndael 发布。最初以 Rijndael 发布。[...]

    [...]Rijndael 密码是由 两位比利时密码学家,琼 Daemen 和 Vincent Rijmen,以及 由他们提交给 AES 选择 过程。 Rijndael(发音为“莱茵河” dall") 是一个文字游戏,其名称为 两位发明者。[...]

    您在解密字符串末尾遇到的\x00 字符是某些block ciphers 所需的padding(ECB 就是这样的分组密码)。如果输入数据需要填充到所需的块长度,Mcyrpt 在内部使用 NULL-padding。还有其他可用的填充模式(使用 Mcyrpt 时必须由用户编码),即 PKCS7、ANSI X.923 或 ISO 10126。NULL-padding 在加密可能以一个或多个结尾的二进制数据时会出现问题\x00 字符,因为您无法检测到数据在哪里结束和填充开始 - 提到的其他填充模式解决了这类问题。如果您正在加密字符数据(字符串),您可以使用 $data = trim($data, "\x00"); 轻松修剪尾随的 \x00

    要解密您发送给消费者的数据,消费者需要知道 IV(初始化向量)($iv)、使用的算法(MCRYPT_RIJNDAEL_256/AES-256)、加密模式(@987654338 @)、秘密加密密钥 ($key) 和使用的填充模式 (NULL-padding)。 IV 可以与加密数据一起传输,因为它不需要保密:

    接受者必须知道 IV 被加密的信息是 能够解密它。这可以是 以多种方式确保:通过 将 IV 与 密文,通过同意 事先在密钥交换期间或 握手,通过计算 (通常是递增的),或通过 测量电流等参数 时间(用于硬件认证 RSA SecurID、VASCO 等令牌 Digipass 等),发件人等 ID 和/或收件人的地址或 ID、文件 ID、数据包、扇区或簇 数字等。许多变量可以 被组合或散列在一起, 取决于协议。取决于协议。

    【讨论】:

    • MCRYPT_RIJNDAEL_256 不是 AES-256,详情请参阅我的回答。
    • Furthermore ECB 不是分组密码,关于如何将 IV 用于 ECB 的描述也是不正确的。它被称为零填充。所以这个答案的每个部分都有重大问题。
    • @MaartenBodewes:不只是批评,在单独的答案或对此答案的编辑中分享您的知识肯定会有所帮助。
    • @StefanGehrig 我每天都在这里分享我的知识。我已经对other answer 投了赞成票;似乎没有必要做任何其他事情。
    【解决方案3】:

    我将要解释的大部分内容都可以从@ircmaxwell 的出色幻灯片中收集到:Cryptography For The Average Developer,您应该立即查看。我将重申他的主要观点之一:避免编写处理加密/解密的代码。除非你了解所有因素,否则你可能会搞砸它。


    MCRYPT_RIJNDAEL_128 与 AES 非常匹配

    Advanced Encryption Standard 由美国国家标准与技术研究院创建。 NIST 从competitive pool of cryptographic experts 中选择了Rijandael 密码

    常见的混淆:AES 和 Mycrpt 中的数字指代不同的东西

    • AES-128 指 128 位密钥大小
    • AES-256 指 256 位密钥大小
    • MCRYPT_RIJNDAEL_128 指的是128 位密码块大小
    • MCRYPT_RIJNDAEL_256 指的是 256 位密码块大小

    密钥大小和块大小

    密钥大小是指用于加密/解密的密钥长度。一个 256 位的密钥是 32 个字节,大约 32 个字符。

    块大小block ciphers(即所有 AES 候选对象)的属性,它在加密过程中将数据分块到特定大小。

    • AES 指定 128 位密码块
    • Mcrypt 的 Rijndaels 都接受 256 位密钥
    • 基于密钥/块大小 MCRYPT_RIJNDAEL_128 似乎最接近 AES-256
      • 还有其他因素需要考虑——比如发生了多少轮转换? — 如果不深入研究源代码,很难验证这一点

    操作模式

    模式是一个重要的元素。

    ECBCBC 模式都将您的纯文本填充到块大小中。如果您使用 128 位块大小加密 1 个字节的数据,您将获得 15 个空字节。填充打开了padding oracle attack 的可能性。

    除了填充之外,ECB 不使用初始化向量 (IV),这让您可以使用 a potential vulnerability:更喜欢 CBCCFB 模式。 p>

    您可以使用 CFB 模式 which does not need padding 避免这两个问题,因此不需要解密后修整。

    初始化向量(IV)

    在创建 IV 时,您需要一个加密强的随机源:MCRYPT_RAND 不够随机 - 首选 MCRYPT_DEV_RANDOMMCRYPT_DEV_URANDOM

    $iv_size = mcrypt_get_iv_size(
        MCRYPT_RIJNDAEL_128,
        MCRYPT_MODE_CFB
    );
    
    $iv = mcrypt_create_iv(
        $iv_size,
        MCRYPT_DEV_URANDOM
    );
    

    最后,为了你的朋友

    为了解密你的朋友需要知道:

    • 密码——MCRYPT_RIJNDAEL_128
    • 块模式 — MCRYPT_MODE_CFB
    • IV — 您加密的每个元素都应该有一个唯一的 IV,因此您需要将 IV 附加到加密数据中
    • 密钥——这是秘密的,对于所有加密都应该保持相同;如果您的密钥被泄露,请将其轮换

    只有密钥需要保密。根据您的传输方法,您应该考虑实施数据完整性检查以确保密文数据未被篡改。同样,请参阅 @ircmaxwell 的出色幻灯片:Cryptography For The Average Developer 以获取使用 hash_hmac() 创建 HMAC 指纹的示例。

    很明显,所有这些活动部件的维护都非常复杂。 小心行事

    其他密码

    Mcrypt 给你其他cipher options。不推荐使用某些方法,例如 DES。其他人是 AES 的候选者,如 Blowfish、TwoFish 和 Serpent。 Rijandael 是经过审查和验证的密码,是recommended

    【讨论】:

      猜你喜欢
      • 2013-12-28
      • 1970-01-01
      • 2018-12-12
      • 2016-01-26
      • 2011-01-27
      • 2011-01-24
      • 2015-11-10
      • 2014-09-12
      • 2014-06-28
      相关资源
      最近更新 更多