ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

用PHP解密AES CTR Little Endian

2019-11-23 09:30:16  阅读:485  来源: 互联网

标签:commoncrypto mcrypt aes cryptography php


我在使用PHP解密使用iOS 5.x的CommonCrypto库加密的字符串时遇到麻烦.以下是参数:

Algorithm: AES-128
Mode: CTR
Mode options: CTR Little-Endian
Padding: None

这是我最大的尝试示例:

<?php
$encrypted = base64_decode('MlNFlnXE1sqIsmKZRtjChBvUMgiJlXgdjHVxQJ6JK24Id4uaN9NK/nBtY+cgrMJR/PRJRCmIUx0boQO5XqJYZ8VJ0w==');
$key = base64_decode('HB+dD1Irj2rXQ/nO+IuqSiK9xVE3PD9cZGIGzrMtwtA=');
$iv = base64_decode('2gxxKYU/G4lj7174e5wj+g==');

$cryptor = mcrypt_module_open('rijndael-128', '', 'ctr', '');
mcrypt_generic_init($cryptor, $key, $iv);
echo mdecrypt_generic($cryptor, $encrypted);

mcrypt_generic_deinit($cryptor);
mcrypt_module_close($cryptor);

输出看起来像这样:

Lorem ipsum dolo?N??]ѕȢ?+?
                                             ????x??k????}??'???Ŧ??;t

但这应该是“ Lorem ipsum dolor坐着,奉献自若,sed do …”(包括尾随省略号.)

块大小为16,并且正确获取了前16个字符.这似乎表明Mcrypt和CommonCrypto之间的AES CTR反增量过程不匹配.到目前为止,我听到的每个人都认为这是Big Endian与Little Endian的问题.

我花了几天时间试图自己找出所有这些字节序和反增量的东西,但是对我来说仍然是巫毒教. :-(我只需要一些PHP代码即可正确地解密我的字符串.我不在乎算法的运行速度.我愿意放弃Mcrypt来支持PHP原生解决方案或其他一些PHP扩展,只要这是很常见的做法,但是,不能在iOS端进行更改.

请帮忙!

解决方法:

分组密码模式非常简单,如果两种实现方式不兼容,则可以自己实现.

这是针对您的特定情况的点击率实现:

function ctr_crypt($str, $key, $iv) {
    $numOfBlocks = ceil(strlen($str) / 16);

    $ctrStr = '';
    for ($i = 0; $i < $numOfBlocks; ++$i) {
        $ctrStr .= $iv;

        // increment IV
        for ($j = 0; $j < 16; ++$j) {
            $n = ord($iv[$j]);
            if (++$n == 0x100) {
                // overflow, set this one to 0, increment next
                $iv[$j] = "\0";
            } else {
                // no overflow, just write incremented number back and abort
                $iv[$j] = chr($n);
                break;
            }
        }
    }

    return $str ^ mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $ctrStr, MCRYPT_MODE_ECB);
}

该算法非常简单:您总是要追加IV并增加IV,直到拥有与输入字符串相比更长(或相等长度)的字符串.然后,使用ECB模式对该字符串进行加密,然后将其与输入字符串进行XOR运算.

在这里,增量是复杂的部分,因为我们正在处理二进制数.小尾数表示我们从左到右递增(j = 0,j <16,j).大尾数将意味着我们从右向左递增(j = 15,j> = 0,j--). 试试看:

$encrypted = base64_decode('MlNFlnXE1sqIsmKZRtjChBvUMgiJlXgdjHVxQJ6JK24Id4uaN9NK/nBtY+cgrMJR/PRJRCmIUx0boQO5XqJYZ8VJ0w==');
$key = base64_decode('HB+dD1Irj2rXQ/nO+IuqSiK9xVE3PD9cZGIGzrMtwtA=');
$iv = base64_decode('2gxxKYU/G4lj7174e5wj+g==');

var_dump(ctr_crypt($encrypted, $key, $iv));
// string(67) "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do..."

注意:ctr_crypt既可以用作加密功能,也可以用作解密功能.

标签:commoncrypto,mcrypt,aes,cryptography,php
来源: https://codeday.me/bug/20191123/2066695.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有