2014-10-05 3 views
1

http 범위 지원을 위해 중간에서 128 ctr 암호화 된 파일을 어떻게 해독합니까? https://www.dropbox.com/s/8e9qembud6n3z7i/encrypted.txt?dl=0부분적으로 AES를 사용하여 Mega.co.nz 파일을 해독합니다. 1283 ctr을 사용하여 스트리밍 범위를 지원합니다.

키 Base64로 암호화된다 : 여기서 암호화 된 파일 E7VQWj3cv1JUi5pklirtDQ9SRJt1DhiqYgzPSpIiVP0

메가 문서 :

Array 
(
    [0] => 330649690 
    [1] => 1037877074 
    [2] => 1418435172 
    [3] => 2519395597 
    [4] => 257049755 
    [5] => 1963858090 
    [6] => 1645006666 
    [7] => 2451723517 
) 
다음 IV가 어레이를 제공하는 키를 복호화함으로써 산출 https://mega.co.nz/#doc

IV는 길이가 2 인 4 번째 오프셋에서 배열을 잘라내서 얻습니다. 그리고 배열의 마지막 두 요소가 채워집니다 파일이 정상하여 해독되고 나서

$key = array($key[0]^$key[4], $key[1]^$key[5], $key[2]^$key[6], $key[3]^$key[7]); 
$key = base64_encode(a32_to_str($key)); 
$iv = base64_encode(a32_to_str($iv)); 

: 0 :

Array 
(
    [0] => 257049755 
    [1] => 1963858090 
    [2] => 0 
    [3] => 0 
) 

그 다음 키 xor의 한 후 PHP 함수 팩 문자열로 변환되고, 128 비트 어레이로 만들어 PHP는 라이브러리. 해독 프로세스에 mcrypt_generic을 사용하고 있습니다. 2 바이트 또는 3 단 또는 중간에서 파일의 암호를 해독하려고하면 문제가 발생합니다. 첫 번째 바이트에서 해독하면 정상적으로 작동합니다.

내가 알아챈 또 다른 사실은, 2 바이트에서 파일을 해독하면 그 전에는 임의의 문자열이나 0을 해독하고 2 바이트에서 해독을 수행한다는 것입니다. IV 블록 카운터와 관련이 있다고 가정합니다. 임의의 바이트를 해독 한 다음 실제 암호를 해독하여 계속 작동합니다. 처음부터 파일의 암호 해독을 시작해야하며 라이브 스트레임 검색을 지원하기 위해 40MB 오프셋에서 말하십시오. 하지만 검색하기 전에 0의 40MB를 해독해야하므로 너무 많은 메모리를 소비합니다. IV 카운터 값을 40mb 오프셋으로 어떻게 옮길 수 있습니까 ??

나는 IV가 해독을 위해 각 블록마다 +1 씩 증가한다는 것을 읽었습니다. 하지만 IV가 배열이기 때문에 1을 더하면 작동하지 않는 모든 것을 시도했습니다. 몇 달 동안 열매를 맺지 않았습니다. AES 128 bit CTR partial file decryption with PHP

답변

0

귀하의 초기 연구는 참으로 올바른 :

여기 프로세스를 조금 이해 도움이 내 앞의 질문입니다 도와주세요. CTR 모드에서 IV (또는 nonce)는 각 암호화 작업 후에 단순히 1 씩 증가합니다. 암호화 및 암호 해독은 CTR 모드에서와 동일한 작업이므로 필요에 따라 한 단어를 다른 단어로 대체 할 수 있습니다.

즉, CTR 모드 암호의 상태는 미리 예측할 수 있습니다. 초기 IV에 이미 암호화 된 블록 특히, 국가는 어떤 방식 으로든 일반 텍스트에 의존하지 않습니다. AES의 블록 크기는 16이므로 암호화 된 바이트 수를 16으로 나눈 값을 더합니다.

IV는 빅 엔디안에 저장된 128 비트 정수로 간주 할 수 있습니다. 사용하는 암호화 API는 4 개의 32 비트 정수 배열로 나타냅니다. 암호를 초기화하기 전에 블록 수를 네 번째 정수에 추가하기 만하면됩니다. 40 억 개 이상의 블록을 처리해야한다고 생각되면 오버 플로우 처리를 세 번째 정수에 추가해야합니다.

약간 더 까다로운 부분은 암호화를 블록 크기로 나눌 수없는 바이트 수를 이미 암호화 한 상태로 초기화하는 것입니다. 해결 방법은 먼저 이미 암호화 된 바이트 수를 16으로 나누고, 반올림 한 다음 암호화 (이미 암호화 된 바이트 수 16) 더미 바이트 수로 암호화를 초기화하는 것입니다. 나는 이것이 당신이 이미 의심했던 것임을 믿습니다.

당신은 PHP에 쓰고있어,하지만 난 그것을하는 데 도움이 경우 자바로 작성한 메가 다운로더 프로그램에서 방법을 게시하도록하겠습니다 :

public Cipher getDownloadCipher(final long startPosition) throws Exception { 
    final Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding"); 
    final ByteBuffer buffer = ByteBuffer.allocate(16).put(nonce); 
    buffer.asLongBuffer().put(startPosition/16); 
    cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "AES"), new IvParameterSpec(buffer.array())); 
    final int skip = (int) (startPosition % 16); 
    if (skip != 0) { 
     if (cipher.update(new byte[skip]).length != skip) { 
      //that should always work with a CTR mode cipher 
      throw new IOException("Failed to skip bytes from cipher"); 
     } 
    } 
    return cipher; 
} 
+0

이 경우'nonce' 필드입니다 8 바이트; 그것은 질문에서 IV의 두 개의 0이 아닌 정수입니다. 'startPosition/16' long은 다른 두 정수입니다. – ntoskrnl