对以下任何帮助都非常感谢.....
我有一些我继承的C ++代码,它解密某些结构/字节数组;我一直在尝试在VB.net中编写一个测试程序,它使用相同的函数来完全模仿C ++解密例程,即。使用WinAPI加密调用;在测试中,CryptAcquireContext,CryptCreateHash,CryptHashData和CryptDeriveKey都成功了;
但是,即使在最简单的情况下,CryptEncrypt和CryptDecrypt函数都会因Invalid Parameter错误而失败;
(我知道System.Security.Cryptography命名空间......我将诉诸于此......但C ++代码包含带有联合的结构,并且为了测试,最好先尝试WinAPI路由)
示例代码如下......我在Win7x64 sp1上,vs 2010 sp1 ...
Private Sub cmdTest(sender As System.Object, e As System.EventArgs) Handles cmdtest.Click
Dim hCrypt As IntPtr
Dim hSecretHash, hUserHash As IntPtr
Dim hSecretKey As IntPtr
Dim success As Boolean
If CryptAcquireContext(hCrypt, vbNullString, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT) Then
'create hash
success = CryptCreateHash(hCrypt, CALG_MD5, 0, 0, hSecretHash)
'hash stage 1
success = CryptHashData(hSecretHash, Encoding.ASCII.GetBytes("yyyyyy"), "xxxxxx".length, 0)
success = CryptHashData(hSecretHash, Encoding.ASCII.GetBytes("yyyyyy"), "yyyyyy".length, 0)
'derive key
success = CryptDeriveKey(hCrypt, CALG_RC4, hSecretHash, 0, hSecretKey)
Dim newb(127) As Byte
Dim teststring As String = "Testing"
Dim testbytes() As Byte = Encoding.ASCII.GetBytes(teststring)
Buffer.BlockCopy(testbytes, 0, newb, 0, testbytes.Length)
Dim inputlength As UShort = Convert.ToUInt16(testbytes.Length)
Dim newblength As UShort = CUShort(newb.Length)
Dim bufferlength As UShort = newblength
'---------------BOTH THESE FAIL (all above OK)
success = CryptEncrypt(hSecretKey, 0, True, 0, newb, newblength, inputlength)
success = CryptDecrypt(hSecretKey, 0, True, 0, newb, newblength)
'--------------------------------------------
'Destroy the user keycode
CryptDestroyHash(hUserHash)
'Destroy the secret key
CryptDestroyKey(hSecretKey)
CryptDestroyHash(hSecretHash)
'Release the provider
CryptReleaseContext(hCrypt, 0)
End If
End Sub
Public Const ALG_CLASS_DATA_ENCRYPT As Int32 = 24576
Public Const ALG_CLASS_HASH As Int32 = 32768
Public Const ALG_TYPE_ANY As Int32 = 0
Public Const ALG_SID_RC4 As Int32 = 1
Public Const ALG_SID_RC2 As Int32 = 2
Public Const ALG_SID_MD5 As Int32 = 3
Public Const ALG_SID_SHA1 As Int32 = 4
Public Const ALG_SID_MAC As Int32 = 5
Public Const ALG_SID_HMAC As Int32 = 9
Public Const ALG_TYPE_BLOCK As Int32 = 1536
Public Const ALG_TYPE_STREAM As Int32 = 2048
Public Const CALG_MD5 As Int32 = ALG_CLASS_HASH + ALG_TYPE_ANY + ALG_SID_MD5
Public Const CALG_RC2 As Int32 = ALG_CLASS_DATA_ENCRYPT + ALG_TYPE_BLOCK + ALG_SID_RC2
Public Const CALG_RC4 As Int32 = ALG_CLASS_DATA_ENCRYPT + ALG_TYPE_STREAM + ALG_SID_RC4
Public Const CALG_SHA1 As Int32 = ALG_CLASS_HASH + ALG_TYPE_ANY + ALG_SID_SHA1
Public Const CALG_MAC As Int32 = ALG_CLASS_HASH + ALG_TYPE_ANY + ALG_SID_MAC
Public Const CALG_HMAC As Int32 = ALG_CLASS_HASH + ALG_TYPE_ANY + ALG_SID_HMAC
Public Const PROV_RSA_FULL As Int32 = &H1
Public Const CRYPT_VERIFYCONTEXT As Int32 = &HF0000000
Public Const HP_ALGID As Int32 = 1
Public Const HP_HASHVAL As Int32 = 2
Public Const HP_HASHSIZE As Int32 = 4
Public Const HP_HMAC_INFO As Int32 = 5
Public Const MS_DEF_PROV As String = "Microsoft Base Cryptographic Provider v1.0"
'Imported Functions:
<DllImport("advapi32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
Public Shared Function CryptAcquireContext( _
ByRef hProv As IntPtr, _
ByVal pszContainer As String, _
ByVal pszProvider As String, _
ByVal dwProvType As Int32, _
ByVal dwFlags As Int32 _
) As Boolean
End Function
<DllImport("advapi32.dll", SetLastError:=True)>
Public Shared Function CryptEncrypt( _
ByVal hKey As IntPtr, _
ByVal hHash As IntPtr, _
ByVal Final As Boolean, _
ByVal dwFlags As UShort, _
pbData() As Byte, _
pdwDataLen As UShort, _
ByVal dwBufLen As UShort) As Boolean
End Function
<DllImport("advapi32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)>
Public Shared Function CryptDecrypt( _
ByVal hKey As IntPtr, _
ByVal hHash As IntPtr, _
ByVal Final As Boolean, _
ByVal dwFlags As UShort, _
pbData() As Byte, _
pdwDataLen As UShort _
) As Boolean
End Function
<DllImport("advapi32.dll", SetLastError:=True)> _
Public Shared Function CryptCreateHash( _
ByVal hProv As IntPtr, _
ByVal Algid As Int32, _
ByVal hKey As IntPtr, _
ByVal dwFlags As Int32, _
ByRef phHash As IntPtr _
) As Boolean
End Function
<DllImport("advapi32.dll", SetLastError:=True)> _
Public Shared Function CryptDestroyHash( _
ByVal hHash As IntPtr _
) As Boolean
End Function
<DllImport("advapi32.dll", SetLastError:=True)> _
Public Shared Function CryptHashData( _
ByVal hHash As IntPtr, _
ByVal pbData() As Byte, _
ByVal dwDataLen As Int32, _
ByVal dwFlags As Int32 _
) As Boolean
End Function
<DllImport("advapi32.dll", setlasterror:=True)> _
Public Shared Function CryptDeriveKey( _
ByVal hProv As IntPtr, _
ByVal Algid As Integer, _
ByVal hBaseData As IntPtr, _
ByVal dwflags As Integer, _
ByRef phKey As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
<DllImport("advapi32.dll", SetLastError:=True)> _
Public Shared Function CryptDestroyKey( _
ByVal hKey As IntPtr _
) As Boolean
End Function
答案 0 :(得分:0)
CryptEncrypt的Final参数是BOOL,它是一个32位的int。尝试将参数更改为Final为int32,或使用MarshalAs(UnmanagedType.Bool)
答案 1 :(得分:0)
可能是更多的事情,但立即ByVal dwFlags As UShort
向我看。
msdn将该参数列为:
DWORD dwFlags,
DWORD是4个字节,因此是Int32或Integer(在VB.NET中)