我需要一种 .NET (理想情况下是 C#)vb6
算法,它会产生与我为加密和decrypt
二进制文件所做的相同的结果。我已经尝试寻找代码一周了,但收效甚微。
我从How to encrypt a string in VB6 decrypt VB.NET开始,但这只是解决方案的一半,它使用了RC2
而不是AES
. 经过一番摆弄,我得到了我的vb6
代码,AES
但我找不到c#
产生相同结果的方法。我认为这与我制作Key
and的方式有关IV
。我一直在研究Cryptographic Services ,我的尝试可以分为两种基本类型。我尝试过PasswordDeriveBytes.CryptDeriveKey
并试图使其与aes
. 根本没有成功。并尝试我试图模仿它的行为。下面我将发布我的vb6
代码和我最接近的c#
尝试。我不能 100% 肯定地说vb6
是完美的,所以如果需要在那里进行更改,我愿意接受。我知道有一种方法可以使用 p 调用,并且我知道有一种方法.net dll
可以从 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);
}