在PHP中从RNCryptor AES 256标头检索IV [英] Retrieve IV from RNCryptor AES 256 header in PHP
问题描述
使用最新的RNCryptor来源并尝试将加密的数据发送到PHP脚本。
Using the latest source of RNCryptor and attempting to send the encrypted data to a PHP script.
RNCryptor将IV封装到标题部分,加密数据。
RNCryptor packages the IV into the header section which is prepended onto the actual encrypted data.
- (NSData *)header
{
uint8_t header[2] = {kRNCryptorFileVersion, self.options};
NSMutableData *headerData = [NSMutableData dataWithBytes:header length:sizeof(header)];
if (self.options & kRNCryptorOptionHasPassword) {
[headerData appendData:self.encryptionSalt]; // 8 bytes
[headerData appendData:self.HMACSalt]; // 8 bytes
}
[headerData appendData:self.IV]; // BlockSizeAES128
return headerData;
}
我是新的在PHP中使用二进制数据,以下解压缩函数?
I am new to working with binary data in PHP, am I correct with using the following unpack function?
<?
$baseEncodedString = "...";
$data = mb_convert_encoding($baseEncodedString, "UTF-8", "BASE64" );
$array = unpack("Cversion/Coptions/C8salt/C8hmac/C16iv/C*aes", $data);
print_r($array);
?>
注意:加密的数据在传输前由可可基于Base64编码。
NOTE: The encrypted data is Base64 encoded from cocoa before transmission.
上述PHP脚本返回的数据如...
The above PHP script returns data such as...
Array([version] => 1 [options ] => 1 [salt1] => 109 [salt1] => 109 [salt2] => 209 [salt2] => 195
[salt3] => 185 [salt4] => b $ b 230 [salt8] => 25 [hmac1] => 8 [hmac2] => 152 [hmac3] => 188 [hmac4]
=> 135 [hmac5] => 117 [hmac6] => 169 [hmac7] => 25 [hmac8] => 228 [iv1] => 43 [iv2] => 220 [iv3] => 80 [iv4] > 144 [iv7] => 172 [iv8] => 104 [iv15] => 104 [iv9] => 216 [iv10] [iv15] => 24 [iv16] =>
191 [aes1] => 122 [aes2] => 227 [aes3] => 45 [aes4] => 194 [aes5] =>
57 [aes6] => 123 [aes7] => 28 [aes8] => 130 [aes10] => > 214 [aes14] => 117 [aes15]
=> 56 [aes16] => 168 [aes17] => 54 [aes18] => 198 [aes19] => ] => 138 [aes22] => 67 [aes22] => 67 [aes22] => 67 [aes23] => 223 [aes24] =>
200 [aes25] => [aes29]
=> 103 [aes30] => 139 [aes36] => 243 [aes32] => 199 [aes33] => 214 [aes34] => 214 > 199 [aes37] => 173 [aes37] => 173 [aes38] =>
219 [aes39] => 71 [aes40] => 97 [aes41] => 32 [aes42] => 27 b 248 [aes44] => 175 [aes45] => 203 [aes46] => 123 [aes47] => 21)
Array ( [version] => 1 [options] => 1 [salt1] => 109 [salt2] => 195 [salt3] => 185 [salt4] => 71 [salt5] => 130 [salt6] => 209 [salt7] => 230 [salt8] => 25 [hmac1] => 8 [hmac2] => 152 [hmac3] => 188 [hmac4] => 135 [hmac5] => 117 [hmac6] => 169 [hmac7] => 25 [hmac8] => 228 [iv1] => 43 [iv2] => 220 [iv3] => 80 [iv4] => 102 [iv5] => 142 [iv6] => 144 [iv7] => 172 [iv8] => 104 [iv9] => 216 [iv10] => 45 [iv11] => 155 [iv12] => 117 [iv13] => 188 [iv14] => 67 [iv15] => 24 [iv16] => 191 [aes1] => 122 [aes2] => 227 [aes3] => 45 [aes4] => 194 [aes5] => 57 [aes6] => 123 [aes7] => 28 [aes8] => 130 [aes9] => 110 [aes10] => 122 [aes11] => 97 [aes12] => 118 [aes13] => 214 [aes14] => 117 [aes15] => 56 [aes16] => 168 [aes17] => 54 [aes18] => 198 [aes19] => 113 [aes20] => 120 [aes21] => 138 [aes22] => 67 [aes23] => 223 [aes24] => 200 [aes25] => 11 [aes26] => 109 [aes27] => 177 [aes28] => 167 [aes29] => 103 [aes30] => 139 [aes31] => 243 [aes32] => 199 [aes33] => 214 [aes34] => 214 [aes35] => 241 [aes36] => 199 [aes37] => 173 [aes38] => 219 [aes39] => 71 [aes40] => 97 [aes41] => 32 [aes42] => 27 [aes43] => 248 [aes44] => 175 [aes45] => 203 [aes46] => 123 [aes47] => 21 )
我如何在PHP MCrypt函数中使用这个?
How am I able to use this in the PHP MCrypt functions?
谢谢。
EDIT
为了回应drew010的回答,我将PHP脚本更新为以下...
In response to drew010's answer I have updated my PHP script to the following...
<?
function pbkdf2($algorithm, $password, $salt, $count, $key_length, $raw_output = false)
{
$algorithm = strtolower($algorithm);
if(!in_array($algorithm, hash_algos(), true))
die('PBKDF2 ERROR: Invalid hash algorithm.');
if($count <= 0 || $key_length <= 0)
die('PBKDF2 ERROR: Invalid parameters.');
$hash_length = strlen(hash($algorithm, "", true));
$block_count = ceil($key_length / $hash_length);
$output = "";
for($i = 1; $i <= $block_count; $i++) {
// $i encoded as 4 bytes, big endian.
$last = $salt . pack("N", $i);
// first iteration
$last = $xorsum = hash_hmac($algorithm, $last, $password, true);
// perform the other $count - 1 iterations
for ($j = 1; $j < $count; $j++) {
$xorsum ^= ($last = hash_hmac($algorithm, $last, $password, true));
}
$output .= $xorsum;
}
if($raw_output)
return substr($output, 0, $key_length);
else
return bin2hex(substr($output, 0, $key_length));
}
$base = $_GET['base'];
$data = mb_convert_encoding($base, "UTF-8", "BASE64" );
//$data = base64_decode($base);
$header = array();
$header['ver'] = substr($data, 0, 1);
$header['options'] = substr($data, 1, 1);
$header['salt'] = substr($data, 2, 8);
$header['hmac'] = substr($data, 10, 8);
$header['iv'] = substr($data, 18, 16);
$data = substr($data, 34);
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
mcrypt_generic_init($td, pbkdf2('SHA256', 'password', $header['salt'], 10000, 16), $header['iv']);
//$decrypted = mcrypt_decrypt('rijndael-256','password',$data,'',$header['iv']);
$decrypted = mdecrypt_generic($td, $data);
echo $decrypted;
?>
我仍然得到加扰的文字。
How ever I am still getting scrambled text.
U¸¦uÀˆÆ&bŸ8:f`ôShŽºÃ~:¾ÉöÁß=Ç®nqäà€•Æ‹ò
我回顾了RNCryptor并使用了以下的PHP脚本值。
I looked back at RNCryptor and used the following values for the PHP script
static const RNCryptorSettings kRNCryptorAES256Settings = {
.algorithm = kCCAlgorithmAES128,
.blockSize = kCCBlockSizeAES128,
.IVSize = kCCBlockSizeAES128,
.options = kCCOptionPKCS7Padding,
.HMACAlgorithm = kCCHmacAlgSHA256,
.HMACLength = CC_SHA256_DIGEST_LENGTH,
.keySettings = {
.keySize = kCCKeySizeAES256,
.saltSize = 8,
.PBKDFAlgorithm = kCCPBKDF2,
.PRF = kCCPRFHmacAlgSHA1,
.rounds = 10000
},
.HMACKeySettings = {
.keySize = kCCKeySizeAES256,
.saltSize = 8,
.PBKDFAlgorithm = kCCPBKDF2,
.PRF = kCCPRFHmacAlgSHA1,
.rounds = 10000
}
};
这个功能我相信会产生钥匙吗?
This function I believe produces the key?
+ (NSData *)keyForPassword:(NSString *)password salt:(NSData *)salt settings:(RNCryptorKeyDerivationSettings)keySettings
{
NSMutableData *derivedKey = [NSMutableData dataWithLength:keySettings.keySize];
int result = CCKeyDerivationPBKDF(keySettings.PBKDFAlgorithm, // algorithm
password.UTF8String, // password
password.length, // passwordLength
salt.bytes, // salt
salt.length, // saltLen
keySettings.PRF, // PRF
keySettings.rounds, // rounds
derivedKey.mutableBytes, // derivedKey
derivedKey.length); // derivedKeyLen
// Do not log password here
// TODO: Is is safe to assert here? We read salt from a file (but salt.length is internal).
NSAssert(result == kCCSuccess, @"Unable to create AES key for password: %d", result);
return derivedKey;
}
再次感谢。
是MCRYPT_RIJNDAEL_128是否正确?即使RNCryptor设置建议其使用256,实际算法是128,并且IV大小与128块大小相关。我已经读某处强制PHP使用16字节IV,你必须使用MCRYPT_RIJNDAEL_128然后有256饲料一个32字节的密钥。
Is MCRYPT_RIJNDAEL_128 correct? Even though RNCryptor settings suggest its using 256 the actually algorithm is 128 and the IV size relates to the 128 block size. I have read somewhere to force PHP to use the 16 byte IV you must use MCRYPT_RIJNDAEL_128 then to have 256 feed it a 32 byte key.
推荐答案
这适用于我的最新的RNCryptor在iOS
This works for me with the latest RNCryptor in iOS
$ b64_data
:base64编码加密数据< br>
$ pwd
:password
$b64_data
: base64-encoded encrypted data
$pwd
: password
// back to binary
$bin_data = mb_convert_encoding($b64_data, "UTF-8", "BASE64");
// extract salt
$salt = substr($bin_data, 2, 8);
// extract HMAC salt
$hmac_salt = substr($bin_data, 10, 8);
// extract IV
$iv = substr($bin_data, 18, 16);
// extract data
$data = substr($bin_data, 34, strlen($bin_data) - 34 - 32);
// extract HMAC
$hmac = substr($bin_data, strlen($bin_data) - 32);
// make HMAC key
$hmac_key = $this->pbkdf2('SHA1', $password, $hmac_salt, 10000, 32, true);
// make HMAC hash
$hmac_hash = hash_hmac('sha256', $data , $hmac_key, true);
// check if HMAC hash matches HMAC
if($hmac_hash != $hmac) return false;
// make data key
$key = $this->pbkdf2('SHA1', $password, $salt, 10000, 32, true);
// decrypt
$ret = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_CBC, $iv);
return trim(preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x80-\xFF]/u', '', $ret));
pbkdf2
,从 https://defuse.ca/php-pbkdf2.htm 。
这篇关于在PHP中从RNCryptor AES 256标头检索IV的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!