0

VB.NET に変換しようとしている VC++ ソース コードにアクセスできます。以前、ビット シフトに関する質問をしたことがあります。回答は理にかなっていて、VB.NET に変換するのはかなり簡単に思えましたが、問題を解決するのに苦労しています。VB.NET に変換する必要がある VC++ コードを次に示します。

#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 復号化のカウンターとして使用されます。次の VC++ コードは、カウンターの計算に使用されます。

u8 counter[16];

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

これは、私が現在 VB.NET コードを使用している場所です。

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

カウンターを作成するために使用されるコードは次のとおりです。

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 バイト) と XOR されます (AES CTR モード)。エラーなしでコードを実行できますが、復号化されたデータの出力が正しくないため、暗号化に使用されているカウンターを正しく計算していないと思います。

繰り返しになりますが、どんな助けでも大歓迎です。事前に感謝します!

編集: 現在の SwapBits 関数...まだ正しくありません

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

これにより、実際には「算術演算でオーバーフローが発生しました」が発生します。uvalue が値 128 に達するとエラーが発生します。値 1 が SwapBits に渡されると、戻り値 = 72057594037927936 になります。VC++ コードの私の解釈では、カウンターは単純に毎回 1 ずつインクリメントする 16 バイト配列である必要があります。たとえば、

uvalue = 1

次に、私のカウンターが必要です

0000000100000000

もしも

uvalue = 25

次に、私のカウンターが必要です

0000002500000000

などなど... または、どこかで何かを誤解していますか?

4

2 に答える 2

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) を取得します。

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

私はC ++の経験があまりありません。これが何をしているのかを共有したいと思います:

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

基本的に、コードのそのセクションは、 counter の最初の 8 バイトを反復ごとに 0f ずつインクリメントiし、右端のバイトから開始し、キャリーオーバーごとに左に拡張します。たとえば、カウンターが 999 に達した場合、counter[7] は 231(&HE7) を保持し、counter[6] 3(&H3) を保持します。これは、配列全体を見ると &H000000000003E7 となり、これは 10 進数の 999 に相当します。

于 2014-01-20T15:50:16.627 に答える
0

GetBytesおよびToUInt64()メソッド、forループ、および一時変数を使用して変換を行う方がよいことがわかります。はるかに読みやすく、おそらくほとんどの目的には十分な速さです。

于 2014-01-20T17:03:07.850 に答える