2012-06-05 4 views
3

나는 몇 시간 동안 이것을보고 보았다. 필자는 iOS에서 AES-256 암호화를 사용하여 짧은 텍스트를 암호화하려고 노력 중이다.이 암호화는 openssl로 해독 할 수있다.iOS에서 AES-256 암호화가 openssl과 동일한 결과를 생성하지 않음

스트레이트 포워드? 아니.

내가 iOS 용 찾은 코드

은 OpenSSL에 대한 키와 IV를와 호환되지 않습니다, 그래서 그것을 적응 했어하지만 분명히 작동하지 않습니다. 그래서 여기

은 (dataString에게) 문자열 키 (키) 및 문자열 초기화 벡터 (IV)를 암호화하는 문자열을 전달 ... 내가 사용하고 암호화하는 코드입니다

- (NSData *)AES256Encrypt:(NSString *)dataString WithKey:(NSString *)key iv:(NSString *)iv { 

    // 'key' should be 32 bytes for AES256, will be null-padded otherwise 
    //char keyPtr[kCCKeySizeAES256+1]; // room for terminator (unused) 
    //bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding) 

    // fetch key data 
    //[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding]; 

    //NSLog(@"keyPtr: '%s'", keyPtr); 

    NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding]; 
    NSLog(@"keyPtr: '%s'", keyData.bytes); 
    NSData *dataToEncrypt = [dataString dataUsingEncoding:NSUTF8StringEncoding]; 
    NSData *ivData = [iv dataUsingEncoding:NSUTF8StringEncoding]; 

    NSUInteger dataLength = [dataToEncrypt length]; 

    //See the doc: For block ciphers, the output size will always be less than or 
    //equal to the input size plus the size of one block. 
    //That's why we need to add the size of one block here 
    size_t bufferSize = dataLength + kCCBlockSizeAES128; 
    void *buffer = malloc(bufferSize); 

    size_t numBytesEncrypted = 0; 
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, 
              keyData.bytes, kCCKeySizeAES256, 
              ivData.bytes, // initialisation vector 
              dataToEncrypt.bytes, 
              dataToEncrypt.length, /* input */ 
              buffer, bufferSize, /* output */ 
              &numBytesEncrypted); 
    if (cryptStatus == kCCSuccess) { 
     //the returned NSData takes ownership of the buffer and will free it on deallocation 
     return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted]; 
    } 

    free(buffer); //free the buffer; 
    return nil; 
} 

동일한 문자열을 인코딩하려면 동일한 키와 iv를 사용하여 openssl을 사용할 때와 같은 값을 생성하지 않습니다. 예를 들면 다음과 같습니다. 이 명령 줄 :

openssl enc -aes-256-cbc -e -in secrets.txt -a -iv 0000 -K 0000 -p 

secrets.txt 그냥 문자열을 포함하는 텍스트 파일이

이이 같은 출력 암호화하는 것입니다

salt=3C66000000000000 
key=0000000000000000000000000000000000000000000000000000000000000000 
iv =00000000000000000000000000000000 
qTMfgtAxbF8Yyh27ZDrcIQ== 

그리고 해독은 반대의 작업을 할 (위의 데이터의 암호화 된 마지막 줄이 test.secrets.out에 있다고 가정)

openssl enc -aes-256-cbc -d -in test.secrets.out -a -iv 0000 -K 0000 -p 
salt=3C66000000000000 
key=0000000000000000000000000000000000000000000000000000000000000000 
iv =00000000000000000000000000000000 
< text of the secrets.txt file > 

이제 4 키의 iv와 iv를 사용하면 iOS에서 올바르게 인코딩되지 않습니다. 전체 길이 키와 iv를 사용하면 올바르게 인코딩되지 않습니다.

기본적으로, 이것은 내가 암호화 된 데이터의 조각을 보낼 경우 데이터의 오른쪽 부분이라고 볼 수있는 검사입니다.

무엇이 누락 되었습니까?

내가 답을 찾으려고을 통해 검토 한 결과 일부 코드 ...

http://robnapier.net/blog/aes-commoncrypto-564

https://github.com/rnapier/RNCryptor

http://pastie.org/426530

유무도 여기에 광범위하게 검색하여 답을 찾을 수 없습니다 .

도움을 주시면 감사하겠습니다.

+0

IOS가 암호화 된 것을 해독 할 수 있는지 확인하십시오. –

+0

Hot Licks와 동의하지만, iOS 가속 루틴을 사용하여 로컬에서 암호화하여 SSL을 통해 다른 것으로 연결하려고한다면 ..... SSL이 AES의 CBC 모드를 사용하고있는 것으로 나타났습니다. iOS를 CBC 모드로 설정 했습니까? AES는 128 비트 청크로 블록을 처리합니다. 아마도 iOS가 리틀 엔디안 또는 대형으로 입력 데이터를 해석하는지 여부를 알아낼 수있는 연구 가치가 있습니다. 이것은 열쇠와 IV에도 적용됩니다. – trumpetlicks

+0

마지막으로 128 비트 블록 (데이터가 128 비트 경계에서 정렬되지 않은 경우)에 대해 데이터가 어떻게 패딩되는지 살펴야 할 수도 있습니다. – trumpetlicks

답변

2

는 OpenSSL IV와 키 암호로 변환하는 ("표준 가깝지, 또한 특히 안전하지"판독) 고유의 방법을 가지고있다. RNOpenSSLCryptor에는 OpenSSL 형식 RNCryptor 지원을 할 수 있습니다 사용

// For aes-128: 
// 
// key = MD5(password + salt) 
// IV = MD5(Key + password + salt) 

// 
// For aes-256: 
// 
// Hash0 = '' 
// Hash1 = MD5(Hash0 + Password + Salt) 
// Hash2 = MD5(Hash1 + Password + Salt) 
// Hash3 = MD5(Hash2 + Password + Salt) 
// Hash4 = MD5(Hash3 + Password + Salt) 
// 
// Key = Hash1 + Hash2 
// IV = Hash3 + Hash4 
// 

// File Format: 
// 
// |Salted___|<salt>|<ciphertext>| 
// 

: 당신이 RNOpenSSLCryptor 보면, 당신은 사용 된 알고리즘을 확인할 수 있습니다. 현재 비동기 작업을 지원하기 위해 async 분기에서이 코드를 재 작업하고 있으며 해당 분기는 아직 OpenSSL을 지원하지 않지만 곧 (2012 년 7 월 중순까지) 재 작업 할 계획입니다.

자신의 용도로이 코드를 구현하려면 keyForPassword:salt:IVForKey:password:salt:을 확인하십시오.

OpenSSL 파일 형식에는 몇 가지 보안 문제가 있으며이를 피할 수 있으면 권장하지 않습니다. 키를 생성하는 데 아주 좋은 KDF를 사용하지 않으며, 무작위로 IV를 가지지 않으며, 인증을 위해 HMAC를 제공하지 않습니다. 이러한 보안 문제로 인해 "호환되지 않는 또 다른 컨테이너"를 만들기가 싫기 때문에 different file format을 설계했습니다.

관련 문제