J'essaye de décrypter un morceau d'un fichier avec wincrypt et je ne peux pas sembler rendre cette fonction décryptée correctement. Les octets sont cryptés avec l'implémentation RC2 en C# et je fournis le même mot de passe et IV au processus de cryptage et de décryptage (crypté en C#, décrypté en C++).Wincrypt: Impossible de déchiffrer le fichier crypté en C#. NTE_BAD_DATA at CryptDecrypt
Toutes mes fonctions en cours retournent vrai jusqu'à la fonction finale "CryptDecrypt". Au lieu de me taper plus, voici la fonction:
static char* DecryptMyFile(char *input, char *password, int size)
{
HCRYPTPROV provider = NULL;
if(CryptAcquireContext(&provider, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, 0))
{printf("Context acquired.");}
else
{
if (GetLastError() == NTE_BAD_KEYSET)
{
if(CryptAcquireContext(&provider, 0, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET))
{printf("new key made.");}
else
{
printf("Could not acquire context.");
}
}
else
{printf("Could not acquire context.");}
}
HCRYPTKEY key = NULL;
HCRYPTHASH hash = NULL;
if(CryptCreateHash(provider, CALG_MD5, 0, 0, &hash))
{printf("empty hash created.");}
else
{printf("could not create hash.");}
if(CryptHashData(hash, (BYTE *)password, strlen(password), 0))
{printf("data buffer is added to hash.");}
else
{printf("error. could not add data buffer to hash.");}
if(CryptDeriveKey(provider, CALG_RC2, hash, 0, &key))
{printf("key derived.");}
else
{printf("Could not derive key.");}
DWORD dwKeyLength = 128;
if(CryptSetKeyParam(key, KP_EFFECTIVE_KEYLEN, reinterpret_cast<BYTE*>(&dwKeyLength), 0))
{printf("success");}
else
{printf("failed.");}
BYTE IV[8] = {0,0,0,0,0,0,0,0};
if(CryptSetKeyParam(key, KP_IV, IV, 0))
{printf("worked");}
else
{printf("faileD");}
DWORD dwCount = size;
BYTE *decrypted = new BYTE[dwCount + 1];
memcpy(decrypted, input, dwCount);
decrypted[dwCount] = 0;
if(CryptDecrypt(key,0, true, 0, decrypted, &dwCount))
{printf("succeeded");}
else
{printf("failed");}
return (char *)decrypted;
}
entrée
est les données transmises à la fonction cryptée. mot de passe est le même mot de passe utilisé pour crypter les données en C#. taille est la taille des données tout crypté.
Toutes les fonctions ci-dessus retournent vrai jusqu'à CryptDecrypt, dont je n'arrive pas à comprendre pourquoi. En même temps, je ne sais pas comment la fonction CryptDecrypt pourrait éditer ma variable "décryptée", puisque je n'en transmets pas de référence.
Toute aide ou conseil sur pourquoi cela ne fonctionne pas serait grandement apprécié. C'est mon premier effort avec wincrypt et la première fois en utilisant C++ dans les années.
Si elle est de plus d'aide, aussi bien, ceci est mon cryptage (en C#):
public static byte[] EncryptString(byte[] input, string password)
{
PasswordDeriveBytes pderiver = new PasswordDeriveBytes(password, null);
byte[] ivZeros = new byte[8];
byte[] pbeKey = pderiver.CryptDeriveKey("RC2", "MD5", 128, ivZeros);
RC2CryptoServiceProvider RC2 = new RC2CryptoServiceProvider();
//using an empty initialization vector for convenience.
byte[] IV = new byte[8];
ICryptoTransform encryptor = RC2.CreateEncryptor(pbeKey, IV);
MemoryStream msEncrypt = new MemoryStream();
CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write);
csEncrypt.Write(input, 0, input.Length);
csEncrypt.FlushFinalBlock();
return msEncrypt.ToArray();
}
Je confirme que ma valeur de hachage en C++ est identique à ma clé en C#, créé par PasswordDeriveBytes.CryptDeriveKey
Vous êtes censé appeler GetLastError() pour obtenir le code d'erreur (NTE_BAD_DATA, NTE_BAD_KEY, NTE_BAD_LEN, etc.) –
Correct. Et j'ai fait et j'ai eu Bad Data comme le mien. – Chris