-1

I'm using wincrypt to encrypt data in the server side, using AES. I want to decrypt data coming from server in the client side. I know that AES uses IV to increase randomization. In python we can specify the IV so it's not a problem to encrypt data and decrypt it in an other application, because we have the abillity to create the same IV and key. I didn't find much about this topic and ways to specify the IV in wincrypt, thus, it makes it harder to decrypt something in an other app. Here are the server relevant functions:

DWORD SomeObj::AcquireContextAndDeriveKey() {
    if (CryptAcquireContext(&this->hCryptProv, NULL, NULL/*Default*/, 
PROV_RSA_AES, CRYPT_VERIFYCONTEXT))
    {
        HCRYPTHASH m_hHashPassword;
        if (CryptCreateHash(this->hCryptProv, CALG_SHA1, 0, 0, 
&m_hHashPassword))
        {
            // Hash for the password. 
            string password = "123456"; // just for this sample
            char hash[255] = { 0 };
            DWORD lenhash = sizeof(hash);
            if (CryptHashData(m_hHashPassword, (BYTE *)password.c_str(), 
(DWORD)strlen(password.c_str()), 0))
            {
                // Session key from the hash
                if (CryptDeriveKey(this->hCryptProv, CALG_AES_256, 
m_hHashPassword, CRYPT_CREATE_SALT, &this->hKey))
                {
                    return ERROR_SUCCESS;
                }
            }
        }
        CleanUp();
    }
    return SERVER_ERROR;
}


DWORD SomeObj::Encrypt(string * To_Enc) {
    DWORD text_len = (To_Enc->length());
    vector<string::value_type> TempBuff(128, 0);
    unsigned nIndex = 0;
    for (auto it = To_Enc->cbegin(); it != To_Enc->cend(); ++it)
    {
        TempBuff[nIndex++] = *it;
    }
    if (!CryptEncrypt(this->hKey,
        NULL,  // hHash = no hash
        1,  // Final
        0,     // dwFlags
        reinterpret_cast<PBYTE>(&TempBuff[0]), //*pbData
        &text_len,  //*pdwDataLen
        TempBuff.size())) {   //dwBufLen
            return SERVER_ERROR;
        }
    To_Enc->assign(&TempBuff[0], text_len);
    return SERVER_SUCCESS;
}

my question is, how can I encrypt data in the server, and decrypt in the client, and whether it is neccessary to specify the IV for that goal, and if it is, how to do it ?

rafiki
  • 91
  • 1
  • 8

1 Answers1

1

A general way to handle an IV is to prefix the encrypted data with its, the IV does not need to be secret. That way the receiver will have the correct iv.

Do use a cryptographically secure pseudo random number generator (CSPRNG) for the IV.

Note: When deriving an encryption key from a password use a key derivation function such as PBKDF2, Rfc2898DeriveBytes, Argon2 or similar functions with a CPU utilization of about 100ms. The point is to make the attacker spend substantial of time finding passwords by brute force.

zaph
  • 111,848
  • 21
  • 189
  • 228