AES 128 CBC를 사용하여 데이터를 암호화하는 iOS 앱이 있습니다. 나는 객관적인 - C에서 응용 프로그램 내에서 해당 데이터를 해독 할 수 있으므로 최소한 암호화가 해당 컨텍스트 (일반 암호화)에서 올바르게 작동한다고 알립니다. 문제는이 암호화 된 데이터를 서버로 보내고 PHP를 통해 해독해야한다는 것입니다. 그것이 내가 실패하고있는 곳입니다.AES 128 암호 해독 실패
수동으로 openssl을 사용하여 명령 줄에서 암호화를 수행했습니다. 이 출력을 사용하여이 php 함수로 다시 입력하면 암호를 올바르게 해독 할 수 있으므로 PHP 함수가 올바르게 작동하는지, 적어도 openssl과 관련하여 알 수 있습니다. 그래서, 문제는 openssl과 같은 방식으로 Objective-C에서 암호문을 출력하는 방법입니다 (또는 PHP로 Common Crypto에서 암호문을 해독하는 방법). 즉, 이러한 각 기능은 자체적 인 맥락에서 작동합니다.
<?php
function jsonEncode ($result, $message) {
$arr = array('result' => $result, 'message' => $message);
echo json_encode($arr);
}
//$ciphertext = base64_decode($_POST['ciphertext']);
//$iv = $_POST['iv'];
// overriding the http post values with values copied in from console output for testing
$ciphertext = base64_decode('dwb7MWCQUUiVuJLzL2EzYm0NcodwORP47qPhLzaolAk=');
// openssl on the command line yields ciphertext of
// 'gRiOXseXTjhpPCiiHgnaQQoal3a9E87Gx3FVpZPtR1I=' which decrypts successfully
$iv = 'hkPDfznq1t1UpKrW';
$key = 'T8ZvJba0HHsmiVSD';
//$plaintext = openssl_decrypt($ciphertext, 'aes-128-cbc', $key, false, $iv);
//jsonEncode('success', $plaintext);
// this is the line that fails
$plaintext = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $ciphertext, MCRYPT_MODE_CBC, $iv);
//$padding = ord($plaintext[strlen($plaintext) - 1]);
//jsonEncode('success', substr($plaintext, 0, -$padding));
jsonEncode('success', $plaintext);
?>
편집 : 아래 @Zaph에서 매우 도움이 의견을 바탕으로, 나는 수동으로 패딩을 할 오브젝티브 C에 내 암호화 기능을 다시 작성했습니다. 나는 이것이 정확하다고 생각한다. 그러나 PHP 함수가 반환 될 때 mcrypt_decrypt
함수는 false로 평가됩니다.
- (NSData *)AES128EncryptWithKey:(NSString *)key iv:(NSString *)iv
{
char keyPtr[kCCKeySizeAES128+1];
bzero(keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
char ivPtr[kCCBlockSizeAES128 + 1];
bzero(ivPtr, sizeof(ivPtr));
if (iv) {
[iv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];
}
NSUInteger dataLength = [self length];
int diff = kCCKeySizeAES128 - (dataLength % kCCKeySizeAES128);
int newSize = 0;
if(diff > 0) {
newSize = (int)(dataLength + diff);
}
// manually add padding to the end of the data array
char dataPtr[newSize];
memcpy(dataPtr, [self bytes], [self length]);
for(int i = 0; i < diff; i++) {
dataPtr[i + dataLength] = diff;
}
dataPtr[newSize] = '\0';
size_t bufferSize = newSize + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
// print out the padded array for verification
NSLog(@"diff: %d new size: %d", diff, newSize);
for (int i=0; i<newSize; i++)
printf("0x%x ", dataPtr[i]);
printf("\n");
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
kCCAlgorithmAES128,
0x0000, //No padding
keyPtr,
kCCKeySizeAES128,
ivPtr,
dataPtr,
sizeof(dataPtr),
buffer,
bufferSize,
&numBytesEncrypted);
if(cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
return nil;
}
목표 C 콘솔 출력 :
diff: 12 new size: 32
0x65 0x6e 0x63 0x72 0x79 0x70 0x74 0x69 0x6f 0x6e 0x20 0x69 0x73 0x20 0x74 0x72 0x69 0x63 0x6b 0x79 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc
encrypted text: dwb7MWCQUUiVuJLzL2EzYm0NcodwORP47qPhLzaolAk=
일반 텍스트는 '암호화가 까다 롭다'는 여기에 새로운 목표 C 함수이다.
자신 만의 암호화를 수행하는 이유는 무엇입니까? 당신은 ssl을 사용할 수 있습니다. "자유"를위한 암호화를 제공합니다. –
나는 내 자신의 암호화를하고 있지 않다. Apple Developer Library에서 CommonCrypto를 사용하고 있습니다. – Alex
@MarcB Common Crypto는 Apple의 iOS 용 암호화 라이브러리입니다. OpenSSL은 iOS 용으로 제공되지 않으므로 소스를 가져 와서 쉽게 컴파일 할 수 있어야한다는 의미에서 무료는 아닙니다. – zaph