使用WinAPI的简单AES加密 [英] Simple AES encryption using WinAPI
问题描述
加密(密钥,数据)
,我不用担心初始化向量等。我的输入和密钥将永远是16个字节。 我真的很希望避免与我的应用程序,所以我试图使用每个平台上可用的。在Mac上,这是一个单行的 CCCrypt
。在Windows上,我从$ code> WinCrypt.h 中的API中丢失。他们加密文件的例子大概是600线。
我正在查看 CryptEncrypt
,但我正在下降您必须创建的依赖关系的兔子洞才能调用。
任何人都可以提供使用Windows API进行AES加密的简单示例?当然有一种方法可以一两行。假设你已经有一个128位的密钥和128位的数据加密了。
能够想出来欢迎提出改进意见!
static void encrypt(const QByteArray& data,
const QByteArray&
QByteArray * encrypted){
//创建加密提供者上下文。
HCRYPTPROV hProvider = NULL;
if(!CryptAcquireContext(& hProvider,
NULL,// pszContainer = no named container
NULL,// pszProvider = default provider
PROV_RSA_AES,
CRYPT_VERIFYCONTEXT) ){
throw std :: runtime_error(无法创建加密提供程序上下文);
}
//构造密钥生成所需的blob。
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);
//创建Windows需要的加密密钥结构。
HCRYPTKEY hKey = NULL;
if(!CryptImportKey(hProvider,
reinterpret_cast< BYTE *>(& aes_blob),
sizeof(AesBlob128),
NULL,// hPubKey =未加密
0,// dwFlags
& hKey)){
throw std :: runtime_error(无法创建加密密钥);
}
// CryptEncrypt方法对输入和
//输出(!)使用*相同的*缓冲区,因此我们将要加密的数据复制到输出数组。
//此外,由于某些原因,Windows上的AES-128块密码需要两倍于
//输出缓冲区中的块大小。所以我们调整到这个长度,然后
//然后在完成之后切断多余的。
encrypted-> clear();
encrypted-> append(data);
encrypted-> resize(kAesBytes128 * 2);
//这样作为要编码的字节长度(在输入端)和
//生成的加密数据(在输出端)上使用的字节数。
DWORD length = kAesBytes128;
if(!CryptEncrypt(hKey,
NULL,// hHash = no hash
true,// Final
0,// dwFlags
reinterpret_cast< BYTE *> ;(加密 - > data()),
& length,
encrypted-> length())){
throw std :: runtime_error(Encryption failed
}
//查看上面的评论。
encrypted-> chop(length - kAesBytes128);
CryptDestroyKey(hKey);
CryptReleaseContext(hProvider,0);
}
I need to do simple single-block AES encryption / decryption in my Qt / C++ application. This is a "keep the honest people honest" implementation, so just a basic encrypt(key, data)
is necessary--I'm not worried about initialization vectors, etc. My input and key will always be exactly 16 bytes.
I'd really like to avoid another dependency to compile / link / ship with my application, so I'm trying to use what's available on each platform. On the Mac, this was a one-liner to CCCrypt
. On Windows, I'm getting lost in the API from WinCrypt.h
. Their example of encrypting a file is almost 600 lines long. Seriously?
I'm looking at CryptEncrypt
, but I'm falling down the rabbit hole of dependencies you have to create before you can call that.
Can anyone provide a simple example of doing AES encryption using the Windows API? Surely there's a way to do this in a line or two. Assume you already have a 128-bit key and 128-bits of data to encrypt.
Here's the best I've been able to come up with. Suggestions for improvement are welcome!
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);
}
这篇关于使用WinAPI的简单AES加密的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!