최신 RNCryptor 소스를 사용하고 암호화 된 데이터를 PHP 스크립트로 보내려고합니다.PHP에서 RNCryptor AES 256 헤더에서 IV 검색
RNCryptor는 IV를 실제 암호화 된 데이터 앞에 추가되는 헤더 섹션에 패키징합니다.
- (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의 바이너리 데이터 작업에 익숙하지 않은 경우 다음 언팩 기능을 사용하여 올바르게 수정 했습니까?
<?
$baseEncodedString = "...";
$data = mb_convert_encoding($baseEncodedString, "UTF-8", "BASE64");
$array = unpack("Cversion/Coptions/C8salt/C8hmac/C16iv/C*aes", $data);
print_r($array);
?>
참고 : 암호화 된 데이터는 전송 전 코코아에서 인코딩 된 Base64입니다.
상기 PHP 스크립트는 ...
어레이 ([버전] => 1 [옵션] => 1 salt1] => 109 salt2] => 195 [salt3 같은 데이터를 리턴 ] [> hmac1] => 8 [hmac2] => 152 [hmac3] => 185 [소금 4] => 71 [소금 5] => 130 소금 6 소금 => 209 소금 7 =>230 [소금 8] => [hmac4] => 25 [hmac8] => 228 [iv1] => 43 [iv2] => 220 [iv3] => 188 [hmac4] = > 80 [iv4] => 102 [iv5] => 142 [iv6] => 144 [iv7] => 172 [iv8] 155 [iv12] => 117 [iv13] => 188 [iv14] => 67 [iv15] => 24 [iv16] => 191 [aes1] => 1 [aes6] => 123 [aes7] => 28 [aes8] => 130 [aes9] => 110 [aes2] => 227 [aes3] => 45 [aes4] => 194 [aes5] => 57 [aes6] [aes10] => 117 [aes15] => 56 [aes16] => 168 [aes17] => 54 [aes10] => 012 [aes10] => [aes18] => 198 [aes19] => 113 [aes20] => 120 [aes21] => 138 [aes22] aes26] => 109 [aes27] => 177 [aes28] => 167 [aes29] => 103 [aes31] => 139 [aes31] => 243 [aes32] => 199 [aes33] => 214 [aes34] [aes39] => 71 [aes36] => 199 [aes37] => 173 [aes38] => 012 [aes39] => => 27 [aes43] => 248 [aes44] => 175 [aes46] => 203 [aes46] => 123 [aes47] => 21)
PHP MCrypt 함수에서 어떻게 사용할 수 있습니까?
감사합니다.
편집 나는 다음에 내 PHP 스크립트를 업데이트 한 drew010의 대답에 대응
... 난 아직 텍스트를 스크램블 얻고 어떻게 이제까지
<?
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;
?>
.
U¸|uÀÆ & bŸ8 : f`ôShŽºÃ ~ : ¾ÉöÁß = Ç®nqäà € Æ <• ò
내가 RNCryptor 다시 보니 PHP 스크립트에 대해 다음 값을 사용
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
}
};
이 함수는 키를 생성한다고 생각합니까?
+ (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 블록 크기와 관련이 있습니다. 16 바이트 IV를 사용하기 위해 PHP를 강제로 사용하기 위해 MCRYPT_RIJNDAEL_128을 사용하고 나서 256 바이트를 32 바이트 키로 먹여야합니다.
이것은 HMAC를 제거합니다. HMAC가 없으면 다른 사람이 도중에 메시지를 수정했는지 감지 할 수 없습니다. 공격자가 일반 텍스트의 일부를 알고 있으면 해독이 다르게 읽도록 암호문을 수정할 수 있습니다. 예를 들어 Eve가 Alice가 Bob에게 $ 10을 보내는 것을 알고 있으면 암호를 모른 채 $ 99를 Eve로 보내도록 메시지를 변경할 수 있습니다. 이런 종류의 공격을 막기 때문에 HMAC를 확인하는 것이 좋습니다. (그럼에도 불구하고 코드 덕분에 @bubba_gump.) –
내 기쁨, Rob. 비록 내가 공격자가 그 일을 할 수있는 방법을 알기에 충분히 정교하지는 않지만, 당신이 말하는 것을 이해합니다. 그 구멍을 막기 위해 HMAC를 어떻게 생각할 수 있습니까? –
다음은 파이썬 공격에 대한 단계별 설명입니다. https://github.com/rnapier/security-blunders/blob/master/modaes.py –