2010-02-10 2 views
0

대 내가 해독하는 데 사용하는 목적-C 코드를 RC4 알고리즘 여기 (http://rc4crypt.devhome.org)RC4 암호화 - CommonCrypto (목표 - C) PHP

function encrypt ($pwd, $data, $ispwdHex = 0) 
    { 
     if ($ispwdHex) 
      $pwd = @pack('H*', $pwd); // valid input, please! 

     $key[] = ''; 
     $box[] = ''; 
     $cipher = ''; 

     $pwd_length = strlen($pwd); 
     $data_length = strlen($data); 

     for ($i = 0; $i < 256; $i++) 
     { 
      $key[$i] = ord($pwd[$i % $pwd_length]); 
      $box[$i] = $i; 
     } 
     for ($j = $i = 0; $i < 256; $i++) 
     { 
      $j = ($j + $box[$i] + $key[$i]) % 256; 
      $tmp = $box[$i]; 
      $box[$i] = $box[$j]; 
      $box[$j] = $tmp; 
     } 
     for ($a = $j = $i = 0; $i < $data_length; $i++) 
     { 
      $a = ($a + 1) % 256; 
      $j = ($j + $box[$a]) % 256; 
      $tmp = $box[$a]; 
      $box[$a] = $box[$j]; 
      $box[$j] = $tmp; 
      $k = $box[(($box[$a] + $box[$j]) % 256)]; 
      $cipher .= chr(ord($data[$i])^$k); 
     } 
     return $cipher; 
    } 

암호화 된 서버의 XML 파일입니다 있습니다

 NSData *dataToDecrypt = [NSURLConnection sendSynchronousRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.url.com/fileCrypted.xml"]] returningResponse:nil error:nil]; 
     const void *vplainText; 
     size_t plainTextBufferSize; 


      plainTextBufferSize = [dataToDecrypt length]; 
      vplainText = [dataToDecrypt bytes]; 


     CCCryptorStatus ccStatus; 
     uint8_t *bufferPtr = NULL; 
     size_t bufferPtrSize = 0; 
     size_t movedBytes = 0; 

     bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1); 
     bufferPtr = malloc(bufferPtrSize * sizeof(uint8_t)); 
     memset((void *)bufferPtr, 0x0, bufferPtrSize); 

     NSString *key = @"mykey"; 
     //NSString *initVec = @"init Vec"; 
     const void *vkey = (const void *) [key UTF8String]; 
     const void *vinitVec = (const void *) [initVec UTF8String]; 

size_t keyLength = [[key dataUsingEncoding:NSUTF8StringEncoding] length]; 
     ccStatus = CCCrypt(kCCDecrypt, 
          kCCAlgorithmRC4, 
          0, 
          vkey, 
          kCCKeySizeDES, 
          nil, 
          vplainText, 
          plainTextBufferSize, 
          (void *)bufferPtr, 
          bufferPtrSize, 
          &movedBytes); 
     if (ccStatus == kCCSuccess) NSLog(@"SUCCESS"); 
     /*else*/ if (ccStatus == kCCParamError) return @"PARAM ERROR"; 
     else if (ccStatus == kCCBufferTooSmall) return @"BUFFER TOO SMALL"; 
     else if (ccStatus == kCCMemoryFailure) return @"MEMORY FAILURE"; 
     else if (ccStatus == kCCAlignmentError) return @"ALIGNMENT"; 
     else if (ccStatus == kCCDecodeError) return @"DECODE ERROR"; 
     else if (ccStatus == kCCUnimplemented) return @"UNIMPLEMENTED"; 

     NSString *result = [[ NSString alloc ] initWithData: [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes] encoding:NSASCIIEncoding]; 

로그 출력 :

내 RC4 구현 standar을 모두 성공하지만 내 결과가 좋지 않다가 (... 나는 많은 인코딩을 테스트하지만, ASCII가 좋은, 참조, PHP 함수 ORD 것 같다) d?

편집 : 오브젝티브 C 코드 Edit2가 제거 IV : 오브젝티브 C KeyLength = 암호 데이터 길이, 제거 옵션

+0

objectiv-c 코드는 초기화 벡터 _ 및 _ 암호를 사용합니다.귀하의 PHP 코드에서 IV가 보이지 않으며 기본 초기화'$ box [$ i] = $ i; – VolkerK

+0

고맙습니다. 암호 해독은 여전히 ​​작동하지 않지만 괜찮습니다. 나는 뭔가를 놓친 것 같지만, 나는 정말로 암호화가 안 좋습니다. kCCOptionPKCS7Padding이 좋은 옵션입니까? 나는 길을 잃었지만 암호 해독을해야합니다. – Francescu

답변

3

당신이 암호에 무슨 일을하는지 모르는 경우, "롤링하여 - "재해에 대한 확실한 화재 레시피입니다. 당신은 나를 믿을 필요가 없습니다. The Cult of Schneier에 John Viega가 "자신의"암호 작성을 시도하는 일반 프로그래머에 대해 읽어보십시오. 바꿔 치기 : 하지 마십시오.

파일이므로 합리적인 작은 파일을 생각하면 SSL (OpenSSL 및 기타) 또는 OpenPGP (GPG 등)와 같은 표준을 사용하여 더 많은 표준 및 고급 라이브러리를 사용할 수 있습니다 필요한 암호화/해독. Objective-C (또는 iPhone 환경)와 PHP 모두에서 SSL에 대한 라이브러리 또는 모듈 지원이 있다고 생각합니다.

특히 RC4에서는 작성하기가 현저하게 간단하지만 구현 세부 사항에서 엉망진창이 쉬운 스트림 암호입니다. 잘 알려진 역사적인 예에 ​​대해서는 The Misuse of RC4 in Microsoft Word and ExcelCan you recommend RC4 128-bit encrypted software?을 참조하고 보안/암호화 전문가 (전 CTO 및 PGP Corp. 공동 창립자)의 권장 사항을 참조하십시오.


추가 : PHP 스크립트의 키 사이즈는 암호 데이터의 원시 길이를 기반으로

. 또한 PKCS7 패딩을 사용하지 않으므로이 필드는 0이어야합니다 (CCryptor는 스트림 암호의 패딩을 지원하지 않으며 PHP 버전에서는 확실히 사용하지 않습니다). 귀하의 코드에서 CCCrypt는 8 바이트 (64 * 비트)의 키 사이즈를 사용했습니다. 반면 암호 (바이너리 데이터)의 길이 (바이트)를 원한다고 생각합니다.

데이터의 MAC 또는 해시가 없으므로 함수가 유효하지 않은 디코딩으로 유효 여부를 확인할 수 없습니다.

나는이 RC4의 불안 구현 (PHP에서 RC4crypt)와 가까운 호환성을 얻을 것이라 생각합니다.

+0

안녕하세요, 우선 시간을내어 주셔서 감사합니다. 나, 그리고 괜찮 았다고 생각합니다. 그러나 문제는 : 선택의 여지가 없습니다. 콘텐츠 제공 업체가 PHP에서 RC4 암호문을 사용하여 파일을 암호화하고 있으며 키를 제공합니다. 다른 서비스에서 파일을 사용하기 때문에 나를 암호화하도록 변경할 수 없습니다. 이것이 좋은 방법이라고 생각하지 않습니다. 저는 보통 시간 변수가있는 공개/개인 키가있는 API 시스템을 사용하는 것이 좋습니다. 그래서 나는 내가하는 일이 좋은 방법이 아니라는 것을 알고 있습니다. 하지만이 방법으로 iPhone의 파일을 디코딩해야합니다. -/ 모두 최고입니다. – Francescu

+0

이제 알겠습니다. – mctylr

+0

안녕하세요, 도와 주셔서 감사합니다. 변수 keyLength를 추가하고 PKCS7 패딩 옵션을 제거했습니다. ------ 유효하거나 잘못된 디코딩의 경우, 유효한 XML을 얻으면 디코딩이 유효하다는 것을 확신합니다. ---- 오류가 인코딩에서 올 수 있습니까? 정말 바보 같아서 ... : – Francescu

1

건물, 가능하면 자신의 압연 마십시오. RC4가 필요한 경우 사전 빌드/테스트 라이브러리 인 OpenSSL RC4을 사용하십시오. 전체 코드를 약 3 줄로 바꿀 수 있습니다.