php AES256加密兼容性在目标c [英] php AES256 encryption compatibility in objective-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屋!