0

非常感谢您对以下内容的任何帮助......

我有一些我继承的 C++ 代码可以解密某些结构/字节数组;我一直在尝试在 VB.net 中编写一个测试程序,它使用相同的函数完全模仿 C++ 解密例程,即。使用 WinAPI Crypto 调用;在测试中,CryptAcquireContext、CryptCreateHash、CryptHashData和CryptDeriveKey均成功;

但是,即使在最简单的情况下,CryptEncrypt 和 CryptDecrypt 函数都会失败并出现 Invalid Parameter 错误;

(我知道 System.Security.Cryptography 命名空间......我会求助于这个......但是 C++ 代码包含带有联合的结构,并且为了测试,最好先尝试 WinAPI 路由)

示例代码如下...我在 Win7x64 sp1 上,与 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
4

2 回答 2

0

可能是更多的东西,但立即ByVal dwFlags As UShort看向我。

msdn 将该参数列为:

DWORD dwFlags,

DWORD 是 4 个字节,因此是 Int32 或 Integer(在 VB.NET 中)

于 2013-11-21T13:57:00.083 回答
0

CryptEncrypt 的 Final 参数是一个 BOOL,它是一个 32 位的 int。尝试将参数更改为 Final as int32,或使用 MarshalAs(UnmanagedType.Bool)

于 2013-11-15T17:07:17.807 回答