CryptDecrypt

Aus API-Wiki
Zur Navigation springenZur Suche springen

Die Funktion CryptDecrypt entschlüsselt Daten. Zuvor muss ein gültiger Schlüssel mit CryptGenKey oder CryptDeriveKey erstellt worden sein.

Declare Function CryptDecrypt Lib "advapi32.dll" ( _
                 ByVal hKey As Long, _
                 ByVal hHash As Long, _
                 ByVal Final As Long, _
                 ByVal dwFlags As Long, _
                 ByVal pbData As Long, _
                 ByRef pdwDataLen As Long) As Long

Parameter

hKey

[in] Handle eines mit CryptGenKey oder CryptDeriveKey erstellten, oder mit CryptImportKey importierten Schlüssels.

hHash

[in] CryptDecrypt kann gleichzeitig mit dem Entschlüsseln auch einen Hash Wert der entschlüsselten Daten berechnen. Hierzu wird in diesem Parameter das Handle eines mit CryptCreateHash erstellten Hash Objekts übergeben.

Final

[in] In diesem Parameter wird 0 übergeben, wenn mehrere aufeinanderfolgende Datenblöcke durch wiederholtes Aufrufen von CryptDecrypt entschlüsselt werden sollen. Mit dem Aufruf des letzten Blocks setzt man diesen Parameter dann auf 1. Wird CryptDecrypt nur einmal aufgerufen, also nur ein Block entschlüsselt, übergibt man sofort 1.

dwFlags

[in] Es gibt derzeit zwei definierte Flags: CRYPT_OAEP welches im Zusammenhang mit 'Optimal Asymmetric Encryption Padding (OAEP) (PKCS #1 version 2)' verwendet wird und CRYPT_DECRYPT_RSA_NO_PADDING_CHECK welches im Zusamenhang mit RSA Key Blobs verwendet wird. Im allgemeinen kann man diesen Parameter auf 0 setzen.

pbData

[in,out] Zeiger auf die verschlüsselten Daten welche entschlüsselt werden sollen. Auf dem selben Speicherbereich werden auch die entschlüsselten Daten zurückgegeben. Da im allgemeinen die verschlüsselte Variante länger als der Originaltext ist, muss der Buffer nach dem entschlüsseln herunter dimensioniert werden um das korrekte Ergebnis zu erhalten.

dwDataLen

[in,out] Länge der in pbData bereitgestellten, verschlüsselten Daten in Bytes. Nach der Rückkehr der Funktion enthält diese Variable die Länge der entschlüsselten Daten in pbData.

Rückgabe(n)

Bei Erfolg wird ein Wert ungleich 0 zurückgegeben.

Beispiel

Option Explicit

Private Declare Function CryptAcquireContext Lib "advapi32.dll" _
                 Alias "CryptAcquireContextA" ( _
                 ByRef phProv As Long, _
                 ByRef pszContainer As Any, _
                 ByVal pszProvider As String, _
                 ByVal dwProvType As Long, _
                 ByVal dwFlags As Long) As Long

Private Declare Function CryptReleaseContext Lib "advapi32.dll" ( _
                 ByVal hProv As Long, _
                 ByVal dwFlags As Long) As Long
                 
Private Declare Function CryptCreateHash Lib "advapi32.dll" ( _
                 ByVal hProv As Long, _
                 ByVal AlgID As Long, _
                 ByVal hKey As Long, _
                 ByVal dwFlags As Long, _
                 ByRef phHash As Long) As Long

Private Declare Function CryptDestroyHash Lib "advapi32.dll" ( _
                 ByVal hHash As Long) As Long

Private Declare Function CryptDestroyKey Lib "advapi32.dll" ( _
                 ByVal hKey As Long) As Long

Private Declare Function CryptHashData Lib "advapi32.dll" ( _
                 ByVal hHash As Long, _
                 ByVal pbData As Long, _
                 ByVal dwDataLen As Long, _
                 ByVal dwFlags As Long) As Long
                 
Private Declare Function CryptDeriveKey Lib "advapi32.dll" ( _
                 ByVal hProv As Long, _
                 ByVal AlgID As Long, _
                 ByVal hBaseData As Long, _
                 ByVal dwFlags As Long, _
                 ByRef phKey As Long) As Long

Private Declare Function CryptEncrypt Lib "advapi32.dll" ( _
                 ByVal hKey As Long, _
                 ByVal hHash As Long, _
                 ByVal Final As Long, _
                 ByVal dwFlags As Long, _
                 ByVal pbData As Long, _
                 ByRef pdwDataLen As Long, _
                 ByVal dwBufLen As Long) As Long

Private Declare Function CryptDecrypt Lib "advapi32.dll" ( _
                 ByVal hKey As Long, _
                 ByVal hHash As Long, _
                 ByVal Final As Long, _
                 ByVal dwFlags As Long, _
                 ByVal pbData As Long, _
                 ByRef pdwDataLen As Long) As Long

Private Const MS_DEF_PROV As String = _
                    "Microsoft Base Cryptographic Provider v1.0"

Private Const PROV_RSA_FULL        As Long = 1
Private Const CRYPT_VERIFYCONTEXT  As Long = &HF0000000

Private Const HP_HASHVAL As Long = 2
Private Const HP_HASHSIZE As Long = 4

Private Const CRYPT_NO_SALT         As Long = &H10

Private Const NTE_BAD_DATA As Long = &H80090005
Private Const NTE_BAD_ALGID As Long = &H80090008
Private Const NTE_BAD_KEYSET As Long = &H80090016
Private Const NTE_BAD_SIGNATURE As Long = &H80090006

Const ALG_CLASS_KEY_EXCHANGE As Long = &HA000&
Const ALG_CLASS_HASH         As Long = &H8000&
Const ALG_CLASS_DATA_ENCRYPT As Long = &H6000&
Const ALG_CLASS_SIGNATURE    As Long = &H2000&
Const ALG_TYPE_STREAM        As Long = &H800&
Const ALG_TYPE_BLOCK         As Long = &H600&
Const ALG_TYPE_RSA           As Long = &H400&
Const ALG_TYPE_ANY           As Long = 0
Const ALG_SID_RSA_ANY        As Long = 0
Const ALG_SID_MD2            As Long = 1
Const ALG_SID_MD4            As Long = 2
Const ALG_SID_MD5            As Long = 3
Const ALG_SID_SHA            As Long = 4
Const ALG_SID_SHA_256        As Long = 12
Const ALG_SID_SHA_384        As Long = 13
Const ALG_SID_SHA_512        As Long = 14
Const ALG_SID_RC4            As Long = 1
Const ALG_SID_DES            As Long = 1
Const ALG_SID_RC2            As Long = 2
Const ALG_SID_3DES           As Long = 3
Const ALG_SID_3DES_112       As Long = 9
Const ALG_SID_AES_128        As Long = 14
Const ALG_SID_AES_192        As Long = 15
Const ALG_SID_AES_256        As Long = 16
Const ALG_SID_AES            As Long = 17

'Hash Algorithmen:
Enum EnmHashAlgo
    CALG_MD2 = (ALG_CLASS_HASH Or ALG_TYPE_ANY Or ALG_SID_MD2)
    CALG_MD4 = (ALG_CLASS_HASH Or ALG_TYPE_ANY Or ALG_SID_MD4)
    CALG_MD5 = (ALG_CLASS_HASH Or ALG_TYPE_ANY Or ALG_SID_MD5)
    CALG_SHA = (ALG_CLASS_HASH Or ALG_TYPE_ANY Or ALG_SID_SHA)
    CALG_SHA256 = (ALG_CLASS_HASH Or ALG_TYPE_ANY Or ALG_SID_SHA_256)
    CALG_SHA384 = (ALG_CLASS_HASH Or ALG_TYPE_ANY Or ALG_SID_SHA_384)
    CALG_SHA512 = (ALG_CLASS_HASH Or ALG_TYPE_ANY Or ALG_SID_SHA_512)
End Enum

'Encryption:
Public Enum EnmCryptAlgo
    CALG_RC2 = (ALG_CLASS_DATA_ENCRYPT Or ALG_TYPE_BLOCK Or ALG_SID_RC2)
    CALG_RC4 = (ALG_CLASS_DATA_ENCRYPT Or ALG_TYPE_STREAM Or ALG_SID_RC4)
    CALG_DES = (ALG_CLASS_DATA_ENCRYPT Or ALG_TYPE_BLOCK Or ALG_SID_DES)
    CALG_3DES = (ALG_CLASS_DATA_ENCRYPT Or ALG_TYPE_BLOCK Or ALG_SID_3DES)
    CALG_3DES_112 = (ALG_CLASS_DATA_ENCRYPT Or ALG_TYPE_BLOCK Or ALG_SID_3DES_112)
    CALG_AES_128 = (ALG_CLASS_DATA_ENCRYPT Or ALG_TYPE_BLOCK Or ALG_SID_AES_128)
    CALG_AES_192 = (ALG_CLASS_DATA_ENCRYPT Or ALG_TYPE_BLOCK Or ALG_SID_AES_192)
    CALG_AES_256 = (ALG_CLASS_DATA_ENCRYPT Or ALG_TYPE_BLOCK Or ALG_SID_AES_256)
End Enum


Private Sub Command1_Click()
    Dim sTestString As String
    Dim sPassword As String
    Dim btData() As Byte
    Dim hCryptProv As Long
    Dim hHash As Long
    Dim hKey As Long
    Dim cbCipher As Long
    
    Dim x As Long
    Dim sCipher As String
    
    
    sTestString = "Hello World!"
    sPassword = "pssst...Geheim!"
    
    'in ANSI Bytefolge umwandeln:
    btData = StrConv(sTestString, vbFromUnicode)
    
    'Provider Kontext anfordern:
    If CryptAcquireContext(hCryptProv, ByVal 0, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT) = 0 Then
        MsgBox "Kann MS Base Provider nicht finden!", vbExclamation, "Fehler:"
    
    'Hash Objekt erstellen um aus dem Passwort einen Schlüssel zu generieren:
    ElseIf CryptCreateHash(hCryptProv, CALG_SHA, 0, 0, hHash) = 0 Then
        MsgBox "Kann Hash Objekt nicht erstellen!", vbExclamation, "Fehler:"
    
    'Passwort ins Hash Objekt schreiben:
    ElseIf CryptHashData(hHash, StrPtr(sPassword), LenB(sPassword), 0) = 0 Then
        MsgBox "Kann Daten nicht in Hash schreiben!", vbExclamation, "Fehler:"
    
    'Schlüssel erzeugen:
    ElseIf CryptDeriveKey(hCryptProv, CALG_DES, hHash, CRYPT_NO_SALT, hKey) = 0 Then
        If Err.LastDllError = NTE_BAD_ALGID Then
            MsgBox "Algorithmus wird vom CSP nicht unterstützt!", vbExclamation, "Fehler:"
        Else
            MsgBox "Kann Schlüssel nicht erzeugen!", vbExclamation, "Fehler:"
        End If
        
    Else
        'Länge der verschlüsselten Daten ermitteln:
        cbCipher = UBound(btData) + 1
        If CryptEncrypt(hKey, 0, 1, 0, 0, cbCipher, 0) = 0 Then
            MsgBox "Kann Länge nicht ermitteln!", vbExclamation, "Fehler:"
        Else
            'Speicher reservieren und verschlüsselte Daten abholen:
            x = UBound(btData) + 1
            ReDim Preserve btData(cbCipher - 1)
            cbCipher = x
            If CryptEncrypt(hKey, 0, 1, 0, VarPtr(btData(0)), cbCipher, UBound(btData) + 1) = 0 Then
                MsgBox "Kann Daten nicht verschlüsseln!", vbExclamation, "Fehler:"
            Else
                
                'Der verschlüsselte Text liegt nun im Bytearray btData,
                'un wird nun in leserliche HEX Darstellung gebracht:
                For x = 0 To UBound(btData)
                    sCipher = sCipher & " " & Right("0" & Hex(btData(x)), 2)
                Next
                MsgBox "Der Text " & sTestString & " ergibt verschlüsselt die Bytefolge: " & sCipher, vbInformation, "Erfolgreich:"
            
                'jetzt wieder entschlüsseln:
                If CryptDecrypt(hKey, 0, 1, 0, VarPtr(btData(0)), cbCipher) = 0 Then
                    MsgBox "Kann Daten nicht entschlüsseln!", vbExclamation, "Fehler:"
                Else
                    ReDim Preserve btData(cbCipher - 1)
                    sTestString = StrConv(CStr(btData), vbUnicode)
                    MsgBox "Wieder entschlüsselt: " & sTestString, vbInformation, "Erfolgreich:"
                End If
            End If
        End If
    End If

    If hKey <> 0 Then CryptDestroyKey hKey
    If hHash <> 0 Then CryptDestroyHash hHash
    If hCryptProv <> 0 Then CryptReleaseContext hCryptProv, 0
End Sub