我需要一个.NET(理想情况下是C#)算法,它会产生与我加密和解密二进制文件的vb6相同的结果.我一直在努力寻找代码一周,但收效甚微. 我从How to encrypt a string in VB6 decrypt VB.NET开始,但它只有
我从How to encrypt a string in VB6 decrypt VB.NET开始,但它只有一半的解决方案,它使用RC2而不是AES.经过一些摆弄后,我得到了我的vb6代码在AES中工作,但我找不到让c#产生相同结果的方法.我认为这与我制作Key和IV的方式有关.我已经过了Cryptographic Services,我的尝试可以分为两种基本类型.我尝试过PasswordDeriveBytes.CryptDeriveKey并试图让它与aes一起工作的地方.根本没有成功.尝试模仿它的行为. Bellow我将发布我的vb6代码和我最接近的c#尝试.我不能100%肯定地说vb6是完美的所以如果需要在那里做出改变我会对它持开放态度.我知道有一种方法可以使用p调用,我知道有一种方法可以从我的vb应用程序中调用.net dll.我宁愿不这样做.
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); }在我看来,在VB6示例中,您指定了CRYPT_NO_SALT,我相信这会导致使用无初始化向量.据推测,这都是零,但我不确定.
但是在C#代码中,您获取ASCII文本“0000000000000000”的字节,这与字符号{0,0,0,0,… 0}的字节数组不同,因为字符“0”是等于ASCII中的数字48(参见:http://www.asciitable.com/).我认为这可能是你问题的根源.