2009-06-05 3 views
1

Ich habe folgenden nativen Code (Powerbuilder) mit der Crypto API verwendet, um eine Zeichenfolge zu verschlüsseln. Ich brauche C# -Code, um die verschlüsselten Daten zu entschlüsseln. Kann mir jemand einen Tipp oder eine Probe geben?. NET-Entsprechung von diesem nativen Code mit Crypto-API

Danke, Jaap

private function blob of_encryptdecrypt (blob ablob_data, string as_password, boolean ab_encrypt) 
// ----------------------------------------------------------------------------- 
// SCRIPT:  n_cryptoapi.of_EncryptDecrypt 
// 
// PURPOSE: This function will encrypt/decrypt the blob passed to it. Both 
//     encrypt/decrypt have the same api calls except one so they 
//     are combined to save coding. 
// 
// ARGUMENTS: ablob_data - The blob to be decrypted 
//     as_password - The secret password 
// 
// RETURN:  Blob containing the decrypted data. 
// 
// DATE  PROG/ID  DESCRIPTION OF CHANGE/REASON 
// ---------- --------  ----------------------------------------------------- 
// 12/26/2006 RolandS  Initial Coding 
// ----------------------------------------------------------------------------- 

ULong hCryptProv, hHash, hKey 
ULong lul_datalen, lul_buflen, lul_error 
Blob lblob_buffer, lblob_value 
String ls_msgtext 
string ls_password 

// Get handle to CSP 
If Not CryptAcquireContext(hCryptProv, KEY_CONTAINER, is_cryptoservice, PROV_RSA_FULL, 0) Then 
    If Not CryptAcquireContext(hCryptProv, KEY_CONTAINER, is_cryptoservice, PROV_RSA_FULL, CRYPT_NEWKEYSET) Then 
     of_GetLastError(lul_error, ls_msgtext) 
     SignalError(lul_error, "CryptAcquireContext:~r~n~r~n" + ls_msgtext) 
    End If 
End If 

// Create a hash object 
If Not CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, hHash) Then 
    of_GetLastError(lul_error, ls_msgtext) 
    SignalError(lul_error, "CryptCreateHash:~r~n~r~n" + ls_msgtext) 
End If 

// Hash the password 
If Not CryptHashData(hHash,as_password, Len(as_password), 0) Then 
    of_GetLastError(lul_error, ls_msgtext) 
    SignalError(lul_error, "CryptHashData:~r~n~r~n" + ls_msgtext) 
End If 

// Derive a session key from the hash object 
If Not CryptDeriveKey(hCryptProv, ENCRYPT_ALGORITHM, hHash, 0, hKey) Then 
    of_GetLastError(lul_error, ls_msgtext) 
    SignalError(lul_error, "CryptDeriveKey:~r~n~r~n" + ls_msgtext) 
End If 

// allocate buffer space 
lul_datalen = Len(ablob_data) 
lblob_buffer = ablob_data + Blob(Space(8)) 
lul_buflen = Len(lblob_buffer) 

If ab_encrypt Then 
    // Encrypt data 
    If CryptEncrypt(hKey, 0, True, 0, lblob_buffer, lul_datalen, lul_buflen) Then 
     lblob_value = BlobMid(lblob_buffer, 1, lul_datalen) 
    Else 
     of_GetLastError(lul_error, ls_msgtext) 
     SignalError(lul_error, "CryptEncrypt:~r~n~r~n" + ls_msgtext) 
    End If 
Else 
    // Decrypt data 
    If CryptDecrypt(hKey, 0, True, 0, lblob_buffer, lul_datalen) Then 
     lblob_value = BlobMid(lblob_buffer, 1, lul_datalen) 
    Else 
     of_GetLastError(lul_error, ls_msgtext) 
     SignalError(lul_error, "CryptDecrypt:~r~n~r~n" + ls_msgtext) 
    End If 
End If 

// Destroy session key 
If hKey > 0 Then 
    CryptDestroyKey(hKey) 
End If 

// Destroy hash object 
If hHash > 0 Then 
    CryptDestroyHash(hHash) 
End If 

// Release CSP handle 
If hCryptProv > 0 Then 
    CryptReleaseContext(hCryptProv, 0) 
End If 

Return lblob_value 
end function 

Antwort

2

Sie können diese Website überprüfen PInvoke Bezug auf die Crypto-API-Funktionen: http://www.pinvoke.net

Zum Beispiel: [DllImport ("advapi32.dll", SetLastError = true)] public static extern bool CryptHashData (IntPtr hHash, Byte [] PbData, Uint DataLen, Uint Flags);

+0

Warum würden Sie PInvoke Code vorschlagen, wenn .Net in Krypto-Bibliotheken aufgebaut hat? –

+1

Ja, .NET hat eine eigene Krypto-Bibliothek. Aber das war ein Beispiel dafür, wie man die gleichen win32-Funktionen von .NET aufruft (wenn das das ist, was er überhaupt wollte) – Sergiu

3

Sie können das gleiche in C# mit Klassen von System.Security.Cryptography tun.

Sie führen effektiv einen MD5-Hash des Kennworts durch und verwenden dann den Algorithmus, der in der globalen Konstante ENCRYPT_ALGORITHM definiert ist. Sie müssten den Wert dieser Variablen posten, um eine bessere Antwort zu erhalten. Wenn Sie jedoch etwas allgemeines verwenden, gibt es wahrscheinlich einen * CryptoServiceProvider-Wrapper für Sie. Zum Beispiel .

Übrigens kann die Verwendung eines geraden (z. B. nicht gesalzenen) MD5-Hashes des Passworts schlecht sein. Weitere Informationen finden Sie unter this article.

+0

ENCRYPT_ALGORITHM hat tatsächlich den Wert CALG_RC4. Problem ist, dass es in .NET keinen RC4CrypteServiceProvicer gibt. Habe es jetzt in RC2 geändert und habe es nun mit Hilfe des Links zum Beispiel Tjipke funktioniert. – JaapM

+0

Ich würde dringend davon abraten RC2 zu verwenden. Es hat einige bekannte Schwächen. Wenn möglich, rate ich Ihnen, die AES-Chiffre auf beiden Seiten zu verwenden. Sie werden beide von CAPI/CSP unterstützt und haben viel bessere Unterstützung. –