0

VB.NET으로 변환하려고하는 일부 VC++ 소스 코드에 액세스 할 수 있습니다. 나는 이전에 비트 시프 팅에 관한 질문을 던졌고, 주어진 답이 의미가 있었지만 VB.NET으로 변환하는 것이 다소 단순 해 보였지만, 해결하기가 어려웠습니다. AES 128 CTR 모드 카운터 생성을위한 비트 시프트

#define bitShift(_val) \ 
((u64)(((((u64)_val) & 0xff00000000000000ull) >> 56) | \ 
     ((((u64)_val) & 0x00ff000000000000ull) >> 40) | \ 
     ((((u64)_val) & 0x0000ff0000000000ull) >> 24) | \ 
     ((((u64)_val) & 0x000000ff00000000ull) >> 8) | \ 
     ((((u64)_val) & 0x00000000ff000000ull) << 8) | \ 
     ((((u64)_val) & 0x0000000000ff0000ull) << 24) | \ 
     ((((u64)_val) & 0x000000000000ff00ull) << 40) | \ 
     ((((u64)_val) & 0x00000000000000ffull) << 56))) 

지금, 반환 값은 CTR 모드에서 AES 암호 해독 카운터로 사용됩니다 : 여기 VB.NET로 변환 할 필요하고 일부 VC++ 코드입니다. 여기
Public Function SwapBits(ByVal value As Int64) As Int64 
    Dim uvalue As UInt64 = CULng(value) 
    Dim swapped As UInt64 = ((&HFF00000000000000UL) And (uvalue >> 56) Or _ 
          (&HFF000000000000L) And (uvalue >> 40) Or _ 
          (&HFF0000000000L) And (uvalue >> 24) Or _ 
          (&HFF00000000L) And (uvalue >> 8) Or _ 
          (&HFF000000UI) And (uvalue << 8) Or _ 
          (&HFF0000) And (uvalue << 24) Or _ 
          (&HFF00) And (uvalue << 40) Or _ 
          (&HFF) And (uvalue << 56)) 

    Return CLng(swapped) 
End Function 

카운터를 만드는 데 사용되는 코드입니다 : 나는 VB.NET 코드에서 현재 어딘지

u8 counter[16]; 

*(u64 *)(counter + 0) = bitShift(i); 
*(u64 *)(counter + 8) = 0; 

이것은 다음 VC++ 코드는 카운터를 계산하는 데 사용됩니다

Dim blocks As Integer = file_size/16 

For i As Integer = 0 To blocks - 1 
    Dim buffer As Byte() = New Byte(15) {} 
    Array.Copy(BitConverter.GetBytes(SwapBits(CULng(i))), 0, buffer, 0, 8) 

    'AES decryption takes place after this... 

카운터는 16 바이트이지만 처음 8 바이트 만 AES 128 비트 EBC를 사용하여 암호화 된 다음 16 바이트 (AES CTR 모드) 인 현재 암호화 된 데이터 블록과 XOR됩니다. 오류없이 실행할 수있는 코드를 얻을 수 있지만 해독 된 데이터의 출력이 올바르지 않아 암호화에 올바르게 사용되는 카운터를 계산하지 않는다고 생각합니다.

다시 한번 말씀 드리지만, 어떤 도움을 받으셔도 감사 드리며 미리 감사드립니다.

편집 :

Public Function SwapBits(ByVal uvalue As UInt64) As UInt64 
    Dim swapped As UInt64 = ((((uvalue) And &HFF00000000000000) >> 56) Or _ 
          (((uvalue) And &HFF000000000000) >> 40) Or _ 
          (((uvalue) And &HFF0000000000) >> 24) Or _ 
          (((uvalue) And &HFF00000000) >> 8) Or _ 
          (((uvalue) And &HFF000000) << 8) Or _ 
          (((uvalue) And &HFF0000) << 24) Or _ 
          (((uvalue) And &HFF00) << 40) Or _ 
          (((uvalue) And &HFF) << 56)) 

    Return swapped 
End Function 

실제로 원인이 현재 SwapBits 기능 ... 아직하지 못했습니다 불구하고 "산술 연산은 오버플로가 발생했습니다." 오류가 발생하면 uvalue 값이 128에 도달합니다. 1의 값이 SwapBits로 전달되면 반환 값은 72057594037927936입니다. VC++ 코드에 대한 나의 해석은 내 카운터가 매번 1 씩 증가하는 16 바이트 배열이어야한다는 것입니다. 예를 들어,

uvalue = 1 

는 나의 카운터는

uvalue = 25 

다음 내 카운터가

0000002500000000 

등 등 할 필요가

0000000100000000 

경우해야 할 경우 .. 아니면 뭔가 어딘가를 잘못 해석하고있는 것입니까?

+0

각 And 식을 괄호로 그룹화하는 것은 C++ 코드 작성 방법이므로 괄호로 묶어보십시오. – tinstaafl

+0

@tinstaafl, 여전히 잘못된 출력이 나옵니다. 생각해 줘서 고마워. – Jay

+0

또 다른 한가지는 C++ 코드의 16 진수가 모두 동일하게 캐스팅되었지만 vb 코드에서 다르게 캐스팅 된 것입니다. 모두 똑같이 캐스팅하지 않으면 서로 다른 비트 수를 갖게됩니다. – tinstaafl

답변

1

C++ 코드에서 기대하는 것이 확실하지 않습니다.하지만이 사용하는 경우 :

#include <iostream> 

using namespace std; 

#define bitShift(_val) \ 
((unsigned __int64)(((((unsigned __int64)_val) & 0xff00000000000000ull) >> 56) | \ 
     ((((unsigned __int64)_val) & 0x00ff000000000000ull) >> 40) | \ 
     ((((unsigned __int64)_val) & 0x0000ff0000000000ull) >> 24) | \ 
     ((((unsigned __int64)_val) & 0x000000ff00000000ull) >> 8) | \ 
     ((((unsigned __int64)_val) & 0x00000000ff000000ull) << 8) | \ 
     ((((unsigned __int64)_val) & 0x0000000000ff0000ull) << 24) | \ 
     ((((unsigned __int64)_val) & 0x000000000000ff00ull) << 40) | \ 
     ((((unsigned __int64)_val) & 0x00000000000000ffull) << 56))) 


int main() 
{ 
    unsigned __int64 test = bitShift(25); 
    return 0; 
} 

나는이 같은 동일한 반환 값 (1801439850948198400 || & H1900000000000000) 수 : ++ 나 C에 많은 경험이없는

Dim result As ULong = SwapBits(25) 

Public Function SwapBits(ByVal uvalue As UInt64) As UInt64 
    Dim swapped As UInt64 = ((((uvalue) And &HFF00000000000000UL) >> 56) Or _ 
          (((uvalue) And &HFF000000000000UL) >> 40) Or _ 
          (((uvalue) And &HFF0000000000UL) >> 24) Or _ 
          (((uvalue) And &HFF00000000UL) >> 8) Or _ 
          (((uvalue) And &HFF000000UL) << 8) Or _ 
          (((uvalue) And &HFF0000UL) << 24) Or _ 
          (((uvalue) And &HFF00UL) << 40) Or _ 
          (((uvalue) And &HFFUL) << 56)) 

    Return swapped 
End Function 

을주의 이 무엇을하고 있는지 공유 :

u8 counter[16]; 
*(u64 *)(counter + 0) = bitShift(i); 
*(u64 *)(counter + 8) = 0; 

을 기본적으로 해당 섹션 의 코드는 카운터의 첫 번째 8 바이트를 각 반복마다 0fi 씩 증가 시키며 가장 오른쪽 바이트부터 시작하여 각 캐리 오버에 대해 왼쪽으로 확장합니다. 예를 들어, 카운터가 999 카운터 [7]에 도달하면 전체 배열을 볼 때 & H000000000003E7이 999 십진으로 표시되는 231 (& HE7) 및 카운터 [6] 3 (& H3)이됩니다.

+0

이것은 올바른 경로에있는 것처럼 보입니다. 데이터 유형 때문에 for 루프에서 호출 될 때마다 카운터가 1 씩 증가하는 것을 인식하기가 어려웠습니다. 그러나, 잠과 위의 당신의 포스트 후에 그것은 옳은 것처럼 보인다. 저는 C++에서 많은 경험이 없으며,이 일을 공유하려고합니다. 'u8 counter [16]; * (u64 *) (카운터 +0) = bitShift (i); * (u64 *) (카운터 +8) = 0; ' – Jay

+0

전체 C++ 소스 코드 링크가 있습니까? 그 발췌 문장은 의사 코드와 같이 너무 불완전하고보기에 좋지 않습니다. – tinstaafl

+0

여기에 전체 기능 http://pastebin.com/zY4uhtQ2에 대한 링크가 있습니다. 모두 카운터가있는 ECB 모드의 AES 암호화/암호 해독입니다. VB.NET의 문제는 CryptoServiceProvider가 CTR 모드를 지원하지 않는다는 것입니다. 카운터 (8 바이트)는 원래 게시물의 bitShift 함수에 의해 계산됩니다. 암호화 된 데이터는 암호 해독 기능 (16 바이트 데이터 블록)으로 전달되고, 카운터가 계산 된 다음 키로 암호화되고 각 암호화 된 바이트는 암호화 된 카운터의 각 바이트와 XOR됩니다. 내 카운터가 잘못되어 결과가 정확하지 않다고 믿습니다. – Jay

0

무언가는 GetBytesToUInt64() 방법, for 루프 및 임시 변수를 사용하여 변환이 더 잘 이루어 졌다는 것을 알려줍니다. 대부분의 경우 읽기 쉽고 빠를 것입니다.

관련 문제