使用WinAPI进行简单的AES加密

Dav*_*eer 6 c++ encryption winapi aes

我需要在我的Qt/C++应用程序中进行简单的单块AES加密/解密.这是一个"保持诚实的人诚实"的实现,所以只需要一个基本encrypt(key, data)的 - 我不担心初始化向量等.我的输入和密钥总是正好是16个字节.

真的想避免使用我的应用程序编译/链接/发送另一个依赖项,所以我试图使用每个平台上可用的内容.在Mac上,这是一个单行CCCrypt.在Windows上,我迷失在API中WinCrypt.h.他们加密文件的例子几乎是600行.真的吗?

我正在看CryptEncrypt,但是在你打电话之前,我已经陷入了必须创建的依赖性的兔子洞.

任何人都可以提供使用Windows API进行AES加密的简单示例吗?当然,有一种方法可以在一两行中完成.假设您已经有128位密钥和128位数据要加密.

Dav*_*eer 5

这是我能想到的最好的。欢迎提出改进建议!

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);
}
Run Code Online (Sandbox Code Playgroud)