4

バイナリ ファイルを暗号化するために作成したものと同じ結果を生成する.NET (理想的には C#)アルゴリズムが必要です。私は今から 1 週間コードを追い詰めようとしてきましたが、ほとんど成功していません。vb6decrypt

はVB6復号化VB.NETで文字列を暗号化する方法からRC2始めましたが、それは半分の解決策であり、 AES. いくつかいじった後、vb6コードが機能するようになりましたが、同じ結果を生成するAES方法が見つかりません。c#私はそれが私が作っている方法と関係があると思いKeyますIV. 私は暗号化サービスについて調べてきましたが、私の試みは 2 つの基本的なタイプに分けることができます。私が試しPasswordDeriveBytes.CryptDeriveKeyて、それを動作させようとしている場所aes。まったく成功しません。そして、その動作を模倣しようとしたところを試します。vb6以下に、コードと最も近いc#試みを投稿します。100%確実とは言えませんが、vb6完璧なので、そこで変更が必要な場合は、私はそれを受け入れます。.net dllp invoke を使用する方法があり、 my から呼び出されるようにする方法があることを知っていvb appsます。私はそのように行かないほうがいいです。

VB6 関数

Public Function Crypt_File(PathToSourceFile As String, PathToDestFile As String, Password As String, HowTo As CryptMethod) As Boolean
Const FName As String = "mdlCryptography.Encrypt_file"
Dim CryptoContext As Long
Dim strProvider As String
Dim HashHnd As Long
Dim CrypKey As Long
Dim Step As Integer
Dim CryptBuff As String
Dim InFileNum As Long, OutFileNum As Long
Dim BytesRemaining As Long, CurrentBufferSize  As Long
Dim MAX_BUFFER_SIZE As Long
Dim DoCryptFinalise As Long
Dim Buff As String
On Error GoTo Trap:
    Step = 10
    Crypt_File = False
    If PathToSourceFile = PathToDestFile Then '
        Err.Raise 334, FName, "Sourse and Dest Path are the same"
    End If
    MAX_BUFFER_SIZE = (2 ^ 20) * 100 '100 MB
    Buff = vbNullChar
    strProvider = MS_ENH_RSA_AES_PROV_A & vbNullChar
    If Not CBool(CryptAcquireContext(CryptoContext, ByVal Buff, ByVal strProvider, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) Then
        Err.Raise 33410, FName, "Unable to Acquire Context: " & MS_ENH_RSA_AES_PROV_A
    End If

    If Not CBool(CryptCreateHash(CryptoContext, CALG_SHA_256, ByVal 0&, ByVal 0&, HashHnd)) Then
        Err.Raise 33420, FName, "Unable to Create a hash object. " & MS_ENH_RSA_AES_PROV_A
    End If

    If Not CBool(CryptHashData(HashHnd, Password, Len(Password), ByVal 0&)) Then
        Err.Raise 33430, FName, "Unable to Hash password. "
    End If

    If Not CBool(CryptDeriveKey(CryptoContext, CALG_AES_256, HashHnd, ByVal CRYPT_NO_SALT, CrypKey)) Then
        Err.Raise 33440, FName, "Unable to Derive Key. "
    End If
    'Clear HashHnd
    If HashHnd <> 0 Then
        Call CryptDestroyHash(HashHnd)
    End If
    HashHnd = 0

    'Prep Data For encryption
    DoCryptFinalise = 0
    InFileNum = FreeFile
    Step = 20
    Open PathToSourceFile For Binary Access Read As #InFileNum
    If LenB(Dir$(PathToDestFile)) > 0 Then
        Kill PathToDestFile
    End If
    OutFileNum = FreeFile
    Step = 25
    Open PathToDestFile For Binary Access Write As #OutFileNum

    BytesRemaining = LOF(InFileNum)
    'Loop through File Chunks
    Do While BytesRemaining > 0

        If BytesRemaining >= MAX_BUFFER_SIZE Then
            CurrentBufferSize = MAX_BUFFER_SIZE
        Else
            CurrentBufferSize = BytesRemaining
            DoCryptFinalise = 1
        End If

        Buff = String$(CurrentBufferSize, vbNullChar)
        Get #InFileNum, , Buff
            If HowTo = CryptMethod.Encrypt Then
                CryptBuff = EncryptBuffer(CrypKey, DoCryptFinalise, Buff)
            Else
                CryptBuff = DecryptBuffer(CrypKey, DoCryptFinalise, Buff)
            End If
        Put #OutFileNum, , CryptBuff

        BytesRemaining = BytesRemaining - CurrentBufferSize
    Loop
    Close #InFileNum
    Close #OutFileNum
    Crypt_File = True

GoTo Fin
Trap:
    Crypt_File = False
    If Step = 20 Then
        Close #InFileNum
    End If
    If Step = 25 Then
        Close #InFileNum
        Close #OutFileNum
    End If
    Err.Raise Err.Number, Err.source, Err.Description
Fin:

    If CrypKey <> 0 Then
        Call CryptDestroyKey(CrypKey)
    End If
    If HashHnd <> 0 Then
        Call CryptDestroyHash(HashHnd)
    End If
End Function

Private Function EncryptBuffer(CrypKey As Long, DoCryptFinalise As Long, Buff As String) As String
Dim EncDataLength As Long, EnctBuffLen As Long
Dim CryptBuff As String

    EncDataLength = Len(Buff)
    EnctBuffLen = EncDataLength + AES_BLOCK_SIZE
    CryptBuff = String$(EnctBuffLen, vbNullChar)
    LSet CryptBuff = Buff
    If Not CBool(CryptEncrypt(CrypKey, ByVal 0&, ByVal DoCryptFinalise, ByVal 0&, CryptBuff, EncDataLength, EnctBuffLen)) Then
'        Close #InFileNum
'        Close #OutFileNum
        Err.Raise 33450, "mdlCryptography.EncryptBuffer", "Encryption Error"
    End If
    EncryptBuffer = Left$(CryptBuff, EncDataLength)
End Function


Private Function DecryptBuffer(CrypKey As Long, DoCryptFinalise As Long, Buff As String) As String
Dim EncDataLength As Long
Dim CryptBuff As String

    EncDataLength = Len(Buff)
    CryptBuff = String$(EncDataLength, vbNullChar)
    LSet CryptBuff = Buff
    If Not CBool(CryptDecrypt(CrypKey, ByVal 0&, ByVal DoCryptFinalise, ByVal 0&, CryptBuff, EncDataLength)) Then
'        Close #InFileNum
'        Close #OutFileNum
        Err.Raise 33450, "mdlCryptography.DecryptBuffer", "Decryption Error"
    End If
    DecryptBuffer = Left$(CryptBuff, EncDataLength)
End Function

c# 非常に洗練されていない

private void Crypt(bool DoEn)
{
    int Rfc2898KeygenIterations = 100;
    int AesKeySizeInBits = 128;
    byte[] rawPlaintext ;//= System.Text.Encoding.Unicode.GetBytes("This is all clear now!");
    byte[] cipherText = null;
    byte[] plainText = null;

    using (Aes aes = new AesManaged())
    {

        int KeyStrengthInBytes = aes.KeySize / 8;

        SHA256 MySHA = new SHA256Cng();
        MySHA.Initialize();
        plainText = Encoding.ASCII.GetBytes(txtPassword.Text);
        aes.Key = MySHA.ComputeHash(plainText );
        aes.IV =  Encoding.ASCII.GetBytes("0000000000000000");
        if (DoEn)
        {
            //using (FileStream fs = new FileStream(txtOut.Text,FileMode.CreateNew ))
            using (MemoryStream ms = new MemoryStream())
            {
                using (CryptoStream cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write))
                {
                    //using (StreamReader myFile = new StreamReader(txtIn.Text))
                    //{
                    //    rawPlaintext = System.Text.Encoding.ASCII.GetBytes(myFile.ReadToEnd());
                        rawPlaintext = File.ReadAllBytes(txtIn.Text);
                        cs.Write(rawPlaintext, 0, rawPlaintext.Length);

                    //}
                }
                cipherText = ms.ToArray();
                File.WriteAllBytes(txtOut.Text, cipherText);
            }
        }
        else
        {
            //using (FileStream fs = new FileStream(txtIn.Text, FileMode.CreateNew))
            using (MemoryStream ms = new MemoryStream())
            {
                using (CryptoStream cs = new CryptoStream(ms, aes.CreateDecryptor(), CryptoStreamMode.Write))
                {
                    //using (StreamReader myFile = new StreamReader(txtOut.Text))
                    //{
                        //string s = myFile.r.ReadToEnd();
                        rawPlaintext = File.ReadAllBytes(txtOut.Text); //System.Text.Encoding.ASCII.GetBytes(s);
                        //cipherText = new int[rawPlaintext.Length];
                        cs.Write(rawPlaintext, 0, rawPlaintext.Length);
                        //cs.Write(cipherText, 0, cipherText.Length);
                    //}
                }
                cipherText = ms.ToArray();
                File.WriteAllBytes(txtIn.Text, cipherText);
            }
        }
    }
    //string s = System.Text.Encoding.ASCII.GetString(plainText);
    //Console.WriteLine(s);
}
4

2 に答える 2

6

VB6 サンプルでは、​​CRYPT_NO_SALT を指定しているように見えますが、その結果、初期化ベクトルが使用されていないと思います。おそらくこれはすべてゼロですが、よくわかりません。

ただし、C# コードでは、ASCII テキスト "0000000000000000" のバイトを取得しています。これは、文字 '0' がゼロ { 0, 0, 0, 0, ... 0 } のバイト配列と同じではありません。 ASCII の 48 に相当します ( http://www.asciitable.com/を参照)。これがあなたの問題の原因である可能性が高いと思います。

于 2013-01-09T04:04:59.340 に答える
3

ここでのベクトルは、予想とは異なる結果を生成します。

aes.IV = Encoding.ASCII.GetBytes("0000000000000000");

これは、0 ではなく 48 で構成されるバイト配列を返します。

次のように、代わりにバイト配列を単純に初期化できます。

aes.IV = new byte() {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
于 2013-01-09T04:09:31.060 に答える