php AES256加密兼容性在目标c [英] php AES256 encryption compatibility in objective-c

查看:142
本文介绍了php AES256加密兼容性在目标c的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经在php(作为服务)中编写了一个代码来解密通过协议发送的密码。协议要求密码为Mac然后加密(MtE),使用AES256,然后使用base-64编码。



消息结构如这个在php.net上的评论

  base46encoded(iv + ecrypted(mac + password))

该过程很容易使用php

  public static function getPassword($ password,$ key,$ mac_algorithm ='sha1',
$ enc_algorithm = MCRYPT_RIJNDAEL_256,$ enc_mode = MCRYPT_MODE_CBC)
{
//将预共享密钥截断为32字节。
$ key = substr($ key,0,32);

//从base64
$ password = base64_decode($ password)解码消息(作为密码);

//根据算法和加密模式获取iv大小
$ iv_size = mcrypt_get_iv_size($ enc_algorithm,$ enc_mode);

//从消息头(通常是前32个字节)中提取iv用于解密
$ iv_dec = substr($ password,0,$ iv_size);

//在头文件(前32个字节之后)获取加密的消息
$ password = substr($ password,$ iv_size);

//使用预共享密钥解密消息并提取iv
$ password = mcrypt_decrypt($ enc_algorithm,$ key,$ password,$ enc_mode,$ iv_dec);

//获取哈希算法的块大小(sha1块大小为160位)
$ mac_block_size = ceil(static :: getMacAlgoBlockSize($ mac_algorithm)/ 8);

//从解密消息的头中提取mac
$ mac_dec = substr($ password,0,$ mac_block_size);

//提取有价值的消息
$ password = substr($ password,$ mac_block_size);

//消除额外的空终止符,作为enc /解密的结果填充以下if和下一条语句是unpack函数的check子句
$ password = unpack('Z *',$密码);
if(!isset($ password [1]))
{
return false;
}

//从解压缩结果获取纯预期消息(作为密码)
$ password = $ password [1];

//重新生成mac来控制传输的真实性和正确性
$ mac = hash_hmac($ mac_algorithm,$ password,$ key,true);

//看是否传输的mac(mac_dec)和生成的mac是相同的,数据是有效的
如果($ mac_dec == $ mac)
{
返回$密码;
}
else
{
return false;
}
}

现在的问题是,应用程序是围绕着这个开发的我们使用了标准的CCHmac,Base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithCarriageReturn和 CCCrypt的此SO答案

解决方案

mcrypt_generic_init函数通过指定密钥和IV来初始化密码。密钥的长度决定了我们是否正在进行128位,192位或256位加密。



所以使用MCRYPT_RIJNDAEL_128与256位(32 -byte)键与AES256兼容。


I've written a code in php (as a service) to decrypt passwords sent over a protocol. The protocol demands the password to be "Mac then Encrypt"ed (MtE) using AES256, then encoded using base-64.

The message structure is as described in this comment on php.net.

base46encoded (iv + ecrypted(mac + password))

The process was easy using php

public static function getPassword($password, $key, $mac_algorithm = 'sha1',
                                       $enc_algorithm = MCRYPT_RIJNDAEL_256, $enc_mode = MCRYPT_MODE_CBC)
    {
        // truncating pre-shared key to 32 bytes.
        $key = substr($key, 0, 32);

        // decoding the message (being a password) from base64
        $password = base64_decode($password);

        // getting the iv size based on algorithm and encryption mode
        $iv_size = mcrypt_get_iv_size($enc_algorithm, $enc_mode);

        // extracting iv from message header (normally the first 32 byte) for decryption
        $iv_dec = substr($password, 0, $iv_size);

        // getting the encrypted message after the header (after the first 32 byte)
        $password = substr($password, $iv_size);

        // decrypting message using the pre-shared key and extracted iv
        $password = mcrypt_decrypt($enc_algorithm, $key, $password, $enc_mode, $iv_dec);

        // getting block size for hash algorithm in bytes (sha1 block size is 160 bit)
        $mac_block_size = ceil(static::getMacAlgoBlockSize($mac_algorithm)/8);

        // extracting the mac from the header of decrypted message
        $mac_dec = substr($password, 0, $mac_block_size);

        // extracting the valuable message
        $password = substr($password, $mac_block_size);

        // eliminate extra null terminators padded as the result of enc/decryption the following if and the next statement are check clauses for unpack function
        $password = unpack('Z*', $password);
        if (!isset($password[1]))
        {
            return false;
        }

        // obtaining the pure intended message (being the password) from the unpack result
        $password = $password[1];

        // regenerating the mac to control the authenticity and correctness of transmission
        $mac = hash_hmac($mac_algorithm, $password, $key, true);

        // see if transmitted mac (mac_dec) and the generated mac are the same and the data is valid
        if($mac_dec == $mac)
        {
            return $password;
        }
        else
        {
            return false;
        }
    }

Now the problem is, the application is developed around this protocol in iOS, and tried AESCrypt and CCCrypt, but the decryption results are different (gibberish).

We used standard CCHmac, Base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithCarriageReturn and This SO answer for CCCrypt.

解决方案

The mcrypt_generic_init function initializes the cipher by specifying both the key and the IV. The length of the key determines whether we're doing 128-bit, 192-bit, or 256-bit encryption.

So use MCRYPT_RIJNDAEL_128 with a 256-bit (32-byte) key to be compatible with AES256.

这篇关于php AES256加密兼容性在目标c的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆