我已经在php(作为服务)中编写了一个代码来解密通过协议发送的密码。该协议要求密码为" Mac然后使用AES256加密" 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。
答案 0 :(得分:1)
mcrypt_generic_init函数通过指定密钥和IV来初始化密码。密钥的长度决定了我们是否进行了128位,192位或256位加密。
因此,使用带有256位(32字节)密钥的MCRYPT_RIJNDAEL_128与AES256兼容。