2010-03-27 6 views
1

저는 암호를 처음 사용하고 몇 가지 테스트 응용 프로그램을 작성하여 기본 사항을 이해하려고합니다. 알고리즘을 처음부터 만들려고하지는 않지만 서로 다른 두 가지 AES-256 구현 대화를 만들려고합니다.두 AES 알고리즘 간의 상호 운용성

this Javascript implementation이 Base64에 저장되어있는 데이터베이스가 있습니다. 자, 콘텐츠를 해독하기위한 Objective-C 방법을 얻으려고하고 있지만, 구현의 차이점에 대해서는 약간 분실되어 있습니다. 자바 스크립트에서 암호화/해독 할 수 있고 Cocoa에서 암호화/해독 할 수 있지만 Cocoa에서 해독 된 자바 스크립트에서 문자열을 암호화하거나 그 반대의 경우도 마찬가지입니다.

초기화 벡터, 논스 (nonce), 카운터 작동 모드 또는이 모든 것들은 상당히 솔직하게 말해서 나에게 말하지 않는 것으로 생각됩니다.

는 여기에 내가 thisthis 주로 적용, 목표 - C에서 사용하고있는 작업은 다음과 같습니다 물론

@implementation NSString (Crypto) 

- (NSString *)encryptAES256:(NSString *)key { 
    NSData *input = [self dataUsingEncoding: NSUTF8StringEncoding]; 
    NSData *output = [NSString cryptoAES256:input key:key doEncrypt:TRUE]; 
    return [Base64 encode:output]; 
} 

- (NSString *)decryptAES256:(NSString *)key { 
    NSData *input = [Base64 decode:self]; 
    NSData *output = [NSString cryptoAES256:input key:key doEncrypt:FALSE]; 
    return [[[NSString alloc] initWithData:output encoding:NSUTF8StringEncoding] autorelease]; 
} 

+ (NSData *)cryptoAES256:(NSData *)input key:(NSString *)key doEncrypt:(BOOL)doEncrypt { 
    // '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]; 
    NSUInteger dataLength = [input 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 numBytesCrypted = 0; 
    CCCryptorStatus cryptStatus = 
     CCCrypt(doEncrypt ? kCCEncrypt : kCCDecrypt, 
      kCCAlgorithmAES128, 
      kCCOptionECBMode | kCCOptionPKCS7Padding, 
      keyPtr, kCCKeySizeAES256, 
      nil, // initialization vector (optional) 
      [input bytes], dataLength, // input 
      buffer, bufferSize, // output 
      &numBytesCrypted 
     ); 
    if (cryptStatus == kCCSuccess) { 
     // the returned NSData takes ownership of the buffer and will free it on deallocation 
     return [NSData dataWithBytesNoCopy:buffer length:numBytesCrypted]; 
    } 
    free(buffer); // free the buffer; 
    return nil; 
} 

@end 

, 입력이 Base64로 미리 디코딩이다.

Javascript에서 동일한 키와 동일한 내용을 가진 각 암호화는 다른 암호화 된 문자열을 제공합니다. 이는 항상 동일한 암호화 된 문자열을 제공하는 Objective-C 구현의 경우가 아닙니다. this post의 답변을 읽었습니다. 그러면 벡터 초기화 라인을 따라 뭔가 맞는 것 같아 보이지만 정확히 무슨 일이 일어나는지 정확히 알아 내려면 도움이 필요합니다.

감사합니다.

+0

두 가지 대화를 나눌 방법을 찾았습니까 ?? 나는 정확하게 똑같은 문제에 직면하고있다. 그러나 나는이 일을 할 수있는 방법을 찾아 낼 수 없다. 어떤 도움도 인정된다. 감사. –

+0

@Ipfavreau, 나는 당신이했던 것과 같은 문제에 직면하고 있습니다. 그것을 해결 했습니까? 고맙습니다! – AlexR

+1

@AlexR, 아니, 해결하지 못했습니다. Accipitridae가 말한 것은 사실입니다. 두 가지 구현에 차이가 있으며이 경로를 추구하지 않았습니다. – lpfavreau

답변

3

두 가지 구현 간에는 여러 가지 차이점이 있습니다. 대물-C 구현 ECB 모드 (ECB가 약하고 사용해서는 안된다.)

  • 자바 스크립트 된 구현은 키 확장을 사용하여 사용하는 반면

    • 자바 스크립트 구현

      은 CTR 모드를 사용한다. 나는. AES 코드를 전달하기 전에 키를 변환합니다. Objective-C 구현에 대한 확신이 없습니다. 어쨌든 두 가지 구현이 암호화에 동일한 키를 사용하지 않는다는 것을 거의 확신 할 수 있습니다.

    • 자바 스크립트 구현은 현재 시간을 사용하여 암호문 앞에 추가되는 8 바이트 IV를 생성합니다. 이 IV는 CTR 모드의 카운터를 초기화하는 데 사용됩니다. IV 변경으로 인해 동일한 일반 텍스트를 두 번 암호화하면 다른 암호 텍스트가 생성됩니다. 또한 동일한 시계 틱() 내에서 두 개의 암호문을 암호화하지 않는 한 CTR 모드에서 IV를 생성하는 데 현재 시간을 사용하는 것이 좋습니다. Objective-C 구현은 IV를 사용하지 않습니다 (ECB 모드를 사용하기 때문에).

    • Objective-C 코드는 PKCS # 7 패딩을 사용하고 Javascript 코드는 none을 사용합니다. 이것은 고유 한 암호화 모드를 사용하면 생깁니다.

    • 또한 암호문이 어떻게 인코딩되는지 확인해야합니다. Javascript 코드는 Base64 인코딩을 사용합니다. Objective-C 코드는 여러 게시물에 너무 많이 분산되어 있으므로 관련 코드를 찾지 못했습니다.

  • +0

    또한 Objective-C 코드가'kCCAlgorithmAES128'라고 알려주지 만 텍스트에 AES-256을 구현하려고하고 있다고 나와 있습니다. 실수로 더 작은 블록 크기를 사용하고 있습니까? –

    +0

    좋은 답변 감사합니다. 블록 크기에 관해서, Objective-C (기본 CCCrypt 사용)에서 본 AES256의 모든 구현은 kCCAlgorithmAES128을 블록 크기로 사용합니다. 알고있는 kCCAlgorithmAES256을 사용할 수 없습니다. 암호화에 많은 것을 알지 못한다면, 이것이 영향을 미치는지 아니면 표준적인 관행인지는 말할 수 없습니다. 인코딩에 관해서는 둘 다 결과 암호화 된 텍스트에 Base64를 사용하고 있습니다. – lpfavreau

    +1

    AES의 블록 크기는 항상 128 비트입니다. 그러나 키 크기는 다를 수 있습니다. 나는. 키 크기는 128, 192 또는 256 비트가 될 수 있습니다. 따라서 블록 및 키 크기에 대한 위의 사양은 괜찮아 보입니다. – Accipitridae

    0

    테스트의 경우 NIST website for AESFIPS 197의 테스트 값 사용을 고려해야합니다.

    +0

    결과를 어떻게 해석합니까? 두 값 모두에서 암호화 된 결과 문자열이 다르다는 것을 이미 알고 있다면 그 값으로 무엇을 배울 수 있습니까? – lpfavreau