CryptVerifySignature

Aus API-Wiki
Zur Navigation springenZur Suche springen

Mit der Funktion CryptVerifySignature kann die Gültigkeit einer Signatur überprüft werden.

Declare Function CryptVerifySignature Lib "advapi32.dll" _
                 Alias "CryptVerifySignatureA" ( _
                 ByVal hHash As Long, _
                 ByRef pbSignature As Any, _
                 ByVal dwSigLen As Long, _
                 ByVal hPubKey As Long, _
                 ByVal sDescription As Long, _
                 ByVal dwFlags As Long) As Long

Parameter

hHash

[in] Handle eines mit CryptCreateHash erstellten Hash Objekts in welches die signierten Daten mit CryptHashData geschrieben wurden.

pbSignature

[in] Zeiger auf die Signaturdaten die mittels CryptSignHash erstellt wurden.

pdwSigLen

[in] Grösse des in pbSignature bereitgestellten Daten in Bytes.

hPubKey

[in] Handle des öffentlichen Schlüssels mit dem die Daten signiert wurden.

sDescription

[in] Dieser Parameter wird nicht mehr verwendet und muss auf NULL gesetzt werden.

dwFlags

[in] Optionale Parameter:
CRYPT_NOHASHOID
CRYPT_TYPE2_FORMAT
CRYPT_X931_FORMAT

Rückgabe(n)

Bei Erfolg (d.h. die Signatur war gültig) wird ein Wert ungleich 0 zurückgegeben.

Beispiel

Option Explicit

Private Declare Function CryptAcquireContext Lib "advapi32.dll" _
                 Alias "CryptAcquireContextA" ( _
                 ByRef phProv As Long, _
                 ByVal pszContainer As String, _
                 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 CryptSignHash Lib "advapi32.dll" _
                 Alias "CryptSignHashA" ( _
                 ByVal hHash As Long, _
                 ByVal dwKeySpec As Long, _
                 ByVal sDescription As Long, _
                 ByVal dwFlags As Long, _
                 ByRef pbSignature As Any, _
                 ByRef pdwSigLen As Long) As Long
                 
Private Declare Function CryptGenKey Lib "advapi32.dll" ( _
                 ByVal hProv As Long, _
                 ByVal AlgID As Long, _
                 ByVal dwFlags As Long, _
                 ByRef phKey As Long) As Long

Private Declare Function CryptGetUserKey Lib "advapi32.dll" ( _
                 ByVal hProv As Long, _
                 ByVal dwKeySpec As Long, _
                 ByRef phUserKey As Long) As Long
                 
Private Declare Function CryptExportKey Lib "advapi32.dll" ( _
                 ByVal hKey As Long, _
                 ByVal hExhKey As Long, _
                 ByVal dwBlobType As Long, _
                 ByVal dwFlags As Long, _
                 ByRef pbData As Any, _
                 ByRef pdwDataLen As Long) As Long

Private Declare Function CryptImportKey Lib "advapi32.dll" ( _
                 ByVal hProv As Long, _
                 ByRef pbData As Any, _
                 ByVal dwDataLen As Long, _
                 ByVal hPubKey As Long, _
                 ByVal dwFlags As Long, _
                 ByRef phKey As Long) As Long

Private Declare Function CryptVerifySignature Lib "advapi32.dll" _
                 Alias "CryptVerifySignatureA" ( _
                 ByVal hHash As Long, _
                 ByRef pbSignature As Any, _
                 ByVal dwSigLen As Long, _
                 ByVal hPubKey As Long, _
                 ByVal sDescription As Long, _
                 ByVal dwFlags 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_NEWKEYSET      As Long = &H8

Private Const AT_SIGNATURE As Long = 2

Private Const PUBLICKEYBLOB As Long = &H6

Private Const CRYPT_EXPORTABLE      As Long = &H1

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

'Rsa Keyexchange and Signature Algorithmen (asymmetrisch):
Enum EnmRsaKeyTypes
    CALG_RSA_SIGN = (ALG_CLASS_SIGNATURE Or ALG_TYPE_RSA Or ALG_SID_RSA_ANY)
    CALG_RSA_KEYX = (ALG_CLASS_KEY_EXCHANGE Or ALG_TYPE_RSA Or ALG_SID_RSA_ANY)
End Enum

Private Sub Command1_Click()
    Dim sTestDaten As String
    Dim hCryptProv As Long
    Dim hPrivateKey As Long
    Dim hHash As Long
    Dim cbData As Long
    Dim btPublicKey() As Byte
    Dim btSignatureData() As Byte
    Dim hPublicKey As Long
    
    
    sTestDaten = "Hello World!"
    
    '--------------------------------------------------------------------------------------
    'Provider Kontext anfordern und gegebenenfalls RSA Signatur Schlüssel erstellen:
    If CryptAcquireContext(hCryptProv, "Mein Container", MS_DEF_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET) = 0 Then
        'Fehler->Existiert der Container bereits?
        If CryptAcquireContext(hCryptProv, "Mein Container", MS_DEF_PROV, PROV_RSA_FULL, 0) = 0 Then
            MsgBox "Kann MS Base Provider nicht finden!", vbExclamation, "Fehler:"
        
        'bestehenden RSA Signaturschlüssel ermitteln:
        ElseIf CryptGetUserKey(hCryptProv, AT_SIGNATURE, hPrivateKey) = 0 Then
            MsgBox "Kann auf bestehenden Schlüssel nicht zugreifen!", vbExclamation, "Fehler:"
        End If
    Else
        'neuen RSA Signaturschlüssel erzeugen:
        If CryptGenKey(hCryptProv, CALG_RSA_SIGN, CRYPT_EXPORTABLE, hPrivateKey) = 0 Then
            MsgBox "Kann Schlüssel nicht erstellen!", vbExclamation, "Fehler:"
        End If
    End If
    
    
    '--------------------------------------------------------------------------------------
    'Hash Objekt erstellen:
    If CryptCreateHash(hCryptProv, CALG_SHA, 0, 0, hHash) = 0 Then
        MsgBox "Kann Hash Objekt nicht erstellen!", vbExclamation, "Fehler:"
    
    'Die zu signierenden Daten ins Hash Objekt schreiben:
    ElseIf CryptHashData(hHash, StrPtr(sTestDaten), LenB(sTestDaten), 0) = 0 Then
        MsgBox "Kann Daten nicht in Hash schreiben!", vbExclamation, "Fehler:"
    
    'Länge der Signatur Daten ermitteln:
    ElseIf CryptSignHash(hHash, AT_SIGNATURE, 0, 0, ByVal 0, cbData) = 0 Then
        MsgBox "Kann Signatur Länge nicht ermitteln!", vbExclamation, "Fehler:"
    Else
        'Speicher reservieren und Signatur abholen:
        ReDim Preserve btSignatureData(cbData - 1)
        If CryptSignHash(hHash, AT_SIGNATURE, 0, 0, btSignatureData(0), cbData) = 0 Then
            MsgBox "Kann Daten nicht signieren!", vbExclamation, "Fehler:"
        End If
    End If

    '--------------------------------------------------------------------------------------
    'Öffentlichen Teil des Signaturschlüssels exportieren:
    If CryptExportKey(hPrivateKey, 0, PUBLICKEYBLOB, 0, ByVal 0, cbData) = 0 Then
        MsgBox "Kann Schlüssel Länge nicht ermitteln!", vbExclamation, "Fehler:"
    Else
        'Speicher reservieren und Schlüsseldaten abholen:
        ReDim Preserve btPublicKey(cbData - 1)
        If CryptExportKey(hPrivateKey, 0, PUBLICKEYBLOB, 0, btPublicKey(0), cbData) = 0 Then
            MsgBox "Kann Schlüssel nicht exportieren!", vbExclamation, "Fehler:"
        End If
    End If
    
    If hPrivateKey <> 0 Then CryptDestroyKey hPrivateKey
    If hHash <> 0 Then CryptDestroyHash hHash 
    
    '<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    'Die Signaturdaten und die Daten des öffentlichen Schlüssels werden nun weitergegeben
    'und können mit dem folgenden Code überprüft werden:    
    
    '--------------------------------------------------------------------------------------
    'Öffentlichen Schlüssel importieren:
    If CryptImportKey(hCryptProv, btPublicKey(0), UBound(btPublicKey) + 1, 0, 0, hPublicKey) = 0 Then
        MsgBox "Kann Schlüssel nicht importieren!", vbExclamation, "Fehler:"
    
    'Hash Objekt erstellen:
    ElseIf CryptCreateHash(hCryptProv, CALG_SHA, 0, 0, hHash) = 0 Then
        MsgBox "Kann Hash Objekt nicht erstellen!", vbExclamation, "Fehler:"
    
    'Die signierten Daten ins Hash Objekt schreiben:
    ElseIf CryptHashData(hHash, StrPtr(sTestDaten), LenB(sTestDaten), 0) = 0 Then
        MsgBox "Kann Daten nicht in Hash schreiben!", vbExclamation, "Fehler:"
    
    'Signatur überprüfen:
    ElseIf CryptVerifySignature(hHash, btSignatureData(0), UBound(btSignatureData) + 1, hPublicKey, 0, 0) = 0 Then
        MsgBox "Fehler beim überprüfen der Signatur!", vbExclamation, "Fehler:"
    Else
        MsgBox "Signatur ist gültig!", vbInformation, "Erfolg:"
    End If
    
    If hPublicKey <> 0 Then CryptDestroyKey hPublicKey
    If hHash <> 0 Then CryptDestroyHash hHash
    If hCryptProv <> 0 Then CryptReleaseContext hCryptProv, 0
End Sub