2011-11-02 37 views
6

Necesito hacer un simple cifrado/descifrado AES de bloque único en mi aplicación Qt/C++. Esta es una implementación de "mantener a la gente honesta honesta", así que solo es necesario un encrypt(key, data) básico. No me preocupan los vectores de inicialización, etc. Mi entrada y clave siempre serán exactamente 16 bytes.Encriptación AES simple usando WinAPI

Me gustaría realmente me gusta evitar otra dependencia para compilar/vincular/enviar con mi aplicación, por lo que estoy tratando de usar lo que está disponible en cada plataforma. En la Mac, este fue un one-liner a CCCrypt. En Windows, me pierdo en la API desde WinCrypt.h. Su ejemplo de cifrado de un archivo es de casi 600 líneas. en serio?

Estoy buscando CryptEncrypt, pero me estoy cayendo por el agujero de conejo de las dependencias que tiene que crear antes de que pueda llamar eso.

¿Alguien puede dar un ejemplo simple de hacer encriptación AES usando la API de Windows? Seguramente hay una manera de hacer esto en una línea o dos. Supongamos que ya tiene una clave de 128 bits y 128 bits de datos para encriptar.

+0

No puedo proporcionar un ejemplo simple de WinApi (porque es posible que uno no exista como usted señaló), pero ¿ha investigado OpenSSL? Lo he usado en varios proyectos y es bastante sencillo. Sé que no desea agregar otra dependencia, pero puede terminar siendo una solución más simple. – JoeFish

Respuesta

4

Esto es lo mejor que he podido inventar. ¡Sugerencias para mejorar son bienvenidas!

static void encrypt(const QByteArray &data, 
        const QByteArray &key, 
        QByteArray *encrypted) { 
    // Create the crypto provider context. 
    HCRYPTPROV hProvider = NULL; 
    if (!CryptAcquireContext(&hProvider, 
          NULL, // pszContainer = no named container 
          NULL, // pszProvider = default provider 
          PROV_RSA_AES, 
          CRYPT_VERIFYCONTEXT)) { 
    throw std::runtime_error("Unable to create crypto provider context."); 
    } 

    // Construct the blob necessary for the key generation. 
    AesBlob128 aes_blob; 
    aes_blob.header.bType = PLAINTEXTKEYBLOB; 
    aes_blob.header.bVersion = CUR_BLOB_VERSION; 
    aes_blob.header.reserved = 0; 
    aes_blob.header.aiKeyAlg = CALG_AES_128; 
    aes_blob.key_length = kAesBytes128; 
    memcpy(aes_blob.key_bytes, key.constData(), kAesBytes128); 

    // Create the crypto key struct that Windows needs. 
    HCRYPTKEY hKey = NULL; 
    if (!CryptImportKey(hProvider, 
         reinterpret_cast<BYTE*>(&aes_blob), 
         sizeof(AesBlob128), 
         NULL, // hPubKey = not encrypted 
         0,  // dwFlags 
         &hKey)) { 
    throw std::runtime_error("Unable to create crypto key."); 
    } 

    // The CryptEncrypt method uses the *same* buffer for both the input and 
    // output (!), so we copy the data to be encrypted into the output array. 
    // Also, for some reason, the AES-128 block cipher on Windows requires twice 
    // the block size in the output buffer. So we resize it to that length and 
    // then chop off the excess after we are done. 
    encrypted->clear(); 
    encrypted->append(data); 
    encrypted->resize(kAesBytes128 * 2); 

    // This acts as both the length of bytes to be encoded (on input) and the 
    // number of bytes used in the resulting encrypted data (on output). 
    DWORD length = kAesBytes128; 
    if (!CryptEncrypt(hKey, 
        NULL, // hHash = no hash 
        true, // Final 
        0,  // dwFlags 
        reinterpret_cast<BYTE*>(encrypted->data()), 
        &length, 
        encrypted->length())) { 
    throw std::runtime_error("Encryption failed"); 
    } 

    // See comment above. 
    encrypted->chop(length - kAesBytes128); 

    CryptDestroyKey(hKey); 
    CryptReleaseContext(hProvider, 0); 
} 
+2

Esto no funcionará en Windows 2000; no sé si eso es importante o no (bastante desactualizado). Si es así, aquí está la [solución provisional] (http://support.microsoft.com/kb/228786). Además, sus excepciones provocarán fugas en el controlador :) – Luke

+2

No funciona. AesBlob128 no está definido en Windows ... –

Cuestiones relacionadas