微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在GCM模式下使用AES链接BCryptEncrypt调用时,是否可以加密16字节的整数倍?

如何解决在GCM模式下使用AES链接BCryptEncrypt调用时,是否可以加密16字节的整数倍?

启用链接后,是否可以在GCM模式下使用Windows CNG API和AES加密大小不是16字节(128位)的倍数的数据缓冲区?

当我尝试将60字节的缓冲区传递给启用了链接的BCryptEncrypt函数时,出现错误:0xc0000206,它转换为错误字符串:缓冲区的大小对于指定的操作无效。

这是我用来演示我的问题的代码段:

#include <windows.h>
#include <stdio.h>
#include <bcrypt.h>
#pragma comment(lib,"bcrypt.lib")

int main() {
    unsigned char key[16] = { 0xfe,0xff,0xe9,0x92,0x86,0x65,0x73,0x1c,0x6d,0x6a,0x8f,0x94,0x67,0x30,0x83,0x08 };
    unsigned char iv[12] = { 0xca,0xfe,0xba,0xbe,0xfa,0xce,0xdb,0xad,0xde,0xca,0xf8,0x88 };
    unsigned char pt[60] = { 0xd9,0x31,0x32,0x25,0x84,0x06,0xe5,0xa5,0x59,0x09,0xc5,0xaf,0xf5,0x26,0x9a,0xa7,0xa9,0x53,0x15,0x34,0xf7,0xda,0x2e,0x4c,0x3d,0x8a,0x72,0x3c,0x0c,0x95,0x68,0x2f,0xcf,0x0e,0x24,0x49,0xa6,0xb5,0xb1,0xed,0xaa,0x0d,0xe6,0x57,0x63,0x7b,0x39 };
    unsigned char ct[60];
    unsigned char tag[16];

    NTSTATUS bcryptResult = 0;
    DWORD bytesDone = 0;
    BCRYPT_ALG_HANDLE algHandle = 0;
    DWORD blockLength = 16;

    bcryptResult = BCryptOpenAlgorithmProvider(&algHandle,BCRYPT_AES_ALGORITHM,0);
    bcryptResult = BCryptSetProperty(algHandle,BCRYPT_CHAINING_MODE,(BYTE*)BCRYPT_CHAIN_MODE_GCM,sizeof(BCRYPT_CHAIN_MODE_GCM),0);
    BCRYPT_KEY_HANDLE keyHandle = 0;
    bcryptResult = BCryptGenerateSymmetricKey(algHandle,&keyHandle,key,sizeof(key),0);

    /* ---Encrypt data--- */
    {
        unsigned char macContext[16];
        unsigned char contextIV[16];

        BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO authInfo;
        BCRYPT_INIT_AUTH_MODE_INFO(authInfo);
        authInfo.pbNonce = iv;
        authInfo.cbNonce = sizeof(iv);
        authInfo.pbTag = tag;
        authInfo.cbTag = sizeof(tag);

        // Enable chaining of BCryptEncrypt calls
        authInfo.pbMacContext = macContext;
        authInfo.cbMacContext = sizeof(macContext);
        authInfo.dwFlags = BCRYPT_AUTH_MODE_CHAIN_CALLS_FLAG;

        bcryptResult = BCryptEncrypt(keyHandle,pt,sizeof(pt),&authInfo,contextIV,sizeof(contextIV),ct,sizeof(ct),&bytesDone,0);
        if (!BCRYPT_SUCCESS(bcryptResult)) {
            printf("Error: 0x%x \n",bcryptResult);
        }
    
        // disable chaining and call BCryptEncrypt again to get tag
        authInfo.dwFlags &= ~BCRYPT_AUTH_MODE_CHAIN_CALLS_FLAG;
        bcryptResult = BCryptEncrypt(keyHandle,NULL,0);
        if (!BCRYPT_SUCCESS(bcryptResult)) {
            printf("Error: 0x%x",bcryptResult);
        }
    }
    return 0;
}

我注意到两件事。

  1. 加密缓冲区的大小是16字节的倍数,与我提供的代码完美配合。例如,如果将缓冲区pt和ct:s的大小更改为64,则一切正常。
  2. 如果我不启用链接,而只是使用大小为60的缓冲区调用BCryptEncrypt一次,那么一切也可以正常工作,并且我得到了正确的标记

我在Microsoft的CNG文档中找不到与此有关的任何信息。将链接与AES / GCM一起使用时是否有限制?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。