php objective-c 中的 AES256 加密兼容性
php AES256 encryption compatibility in objective-c
我在 php 中编写了一个代码(作为一项服务)来解密通过协议发送的密码。该协议要求使用 AES256 "Mac then Encrypt"ed (MtE) 密码,然后使用 base-64 编码。
消息结构如this comment on 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)
{
// 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;
}
}
现在的问题是,iOS就是围绕这个协议开发的应用,试过AESCrypt和CCCrypt,但是解密结果不一样(乱码)
我们使用标准 CCHmac,Base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithCarriageReturn 和 This SO answer 用于 CCCrypt。
mcrypt_generic_init 函数通过指定密钥和 IV 来初始化密码。密钥的长度决定了我们进行的是 128 位、192 位还是 256 位加密。
所以使用 MCRYPT_RIJNDAEL_128 与 256 位(32 字节)密钥兼容 AES256。
我在 php 中编写了一个代码(作为一项服务)来解密通过协议发送的密码。该协议要求使用 AES256 "Mac then Encrypt"ed (MtE) 密码,然后使用 base-64 编码。
消息结构如this comment on 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)
{
// 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;
}
}
现在的问题是,iOS就是围绕这个协议开发的应用,试过AESCrypt和CCCrypt,但是解密结果不一样(乱码)
我们使用标准 CCHmac,Base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithCarriageReturn 和 This SO answer 用于 CCCrypt。
mcrypt_generic_init 函数通过指定密钥和 IV 来初始化密码。密钥的长度决定了我们进行的是 128 位、192 位还是 256 位加密。
所以使用 MCRYPT_RIJNDAEL_128 与 256 位(32 字节)密钥兼容 AES256。