2009-06-05 7 views
1

J'ai le code natif suivant (Powerbuilder) avec utilise l'API Crypto pour crypter une chaîne. J'ai besoin de code C# pour décrypter les données cryptées. Quelqu'un peut-il me donner un indice ou un échantillon?. Équivalent NET de ce code natif en utilisant crypto api

Merci, 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 

Répondre

2

Vous pouvez consulter ce site pour référence PInvoke aux fonctions CryptoAPI: http://www.pinvoke.net

Par exemple: [DllImport ("advapi32.dll", SetLastError = true)] de extern public static bool CryptHashData (IntPtr hHash, octet [] pbData, uint dataLen, indicateurs uint);

+0

Pourquoi voudriez-vous suggérer un code PInvoke quand .Net a construit dans les bibliothèques crypto? –

+1

Oui, .NET possède sa propre bibliothèque de chiffrement. Mais c'était un exemple de comment appeler les mêmes fonctions win32 à partir de .NET (si c'est ce qu'il voulait en premier lieu) – Sergiu

3

Vous pouvez faire la même chose en C# en utilisant des classes de System.Security.Cryptography.

Vous faites effectivement un hachage MD5 du mot de passe, puis utilisez l'algorithme défini dans une constante globale ENCRYPT_ALGORITHM. Vous devriez afficher la valeur de cette variable pour obtenir une meilleure réponse. Cependant, si vous utilisez quelque chose de commun, il y aura probablement un wrapper * CryptoServiceProvider pour vous. Par exemple, AesCryptoServiceProvider. Par ailleurs, l'utilisation d'un hachage MD5 droit (par exemple non salé) du mot de passe peut être mauvaise. Voir this article pour plus d'informations.

+0

ENCRYPT_ALGORITHM a en fait la valeur CALG_RC4. Le problème est qu'il n'y a aucun RC4CrypteServiceProvicer dans .NET. Changement à RC2 maintenant et l'avoir maintenant travailler avec l'aide du lien vers l'échantillon mentionné par Tjipke. – JaapM

+0

Je vous déconseille vivement d'utiliser RC2. Il a quelques faiblesses connues. Si possible, je conseille d'utiliser le chiffrement AES des deux côtés. Ils sont tous deux soutenus par CAPI/CSP et bénéficient d'un meilleur support. –

Questions connexes