Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C AES-GCM对ESP数据包的解密不起作用_C_Openssl_Aes_Aes Gcm_Evp Cipher - Fatal编程技术网

C AES-GCM对ESP数据包的解密不起作用

C AES-GCM对ESP数据包的解密不起作用,c,openssl,aes,aes-gcm,evp-cipher,C,Openssl,Aes,Aes Gcm,Evp Cipher,我正在尝试解密用AES128-GCM12加密的ESP数据包。我使用c openssl库进行解密。但解密结果是错误的 我使用了两个Linux18.04虚拟机,用strongswan IPsec模拟ESP数据包。我捕获了ESP数据包,并在解密函数中打印了所有变量 static void\u aes\u gcm\u decrypt(uint8\u t*有效载荷、uint16\u t有效载荷、uint8\u t*密钥、uint16\u t密钥、uint8\u t*iv、uint8\u t iv\u le

我正在尝试解密用AES128-GCM12加密的ESP数据包。我使用c openssl库进行解密。但解密结果是错误的

我使用了两个Linux18.04虚拟机,用strongswan IPsec模拟ESP数据包。我捕获了ESP数据包,并在解密函数中打印了所有变量

static void\u aes\u gcm\u decrypt(uint8\u t*有效载荷、uint16\u t有效载荷、uint8\u t*密钥、uint16\u t密钥、uint8\u t*iv、uint8\u t iv\u len、uint8\u t*icv\u len、uint8\u t*aad、uint8\u t aad){
EVP_CIPHER_CTX*CTX;
int outlen;
uint8_t突发[1024];
int-rv;
const EVP_CIPHER*密码;
//忽略盐
键长度-=4;
开关(钥匙){
案例16:密码=EVP_aes_128_gcm();中断;
案例24:cipher=EVP_aes_192_gcm();中断;
案例32:cipher=EVP_aes_256_gcm();中断;
默认:中断;
}
打印十六进制(“原始有效载荷”,有效载荷,有效载荷长度);
打印十六进制(“键”,键,键);
打印十六进制(“iv”,iv,iv_len);
打印十六进制(“icv”,icv,icv_len);
打印十六进制(“aad”,aad,aad_len);
ctx=EVP_CIPHER_ctx_new();
//选择密码
EVP_DecryptInit_ex(ctx,密码,NULL,密钥,iv);
//设置IV长度,省略96位
EVP_密码_CTX_ctrl(CTX,EVP_ctrl_GCM_集合_IVLEN,iv_len,NULL);
//指定键和IV
EVP_DecryptInit_ex(ctx,NULL,NULL,key,iv);
//零个或多个用于指定任何AAD的调用
EVP_解密更新(ctx、NULL和outlen、aad、aad_len);
//解密明文
执行副总裁解密更新(ctx、EXBUF和outlen、有效载荷、有效载荷);
打印十六进制(“解密的负载”,EXPUF,outlen);
执行副总裁密码、CTX、CTR(CTX、执行副总裁控制、GCM、设置标签、icv、icv);
rv=执行副总裁(ctx、icv和outlen);
printf(“标记验证%s\n”,rv>0?“成功!”:“失败!”);
无密码(CTX)的执行副总裁;
}
这是我捕获的数据包

04:51:57.347960 IP (tos 0x0, ttl 64, id 48604, offset 0, flags [DF], proto ESP (50), length 136)
    pc2 > 10.10.10.100: ESP(spi=0xc08247f5,seq=0x2), length 116
        0x0000:  0011 2233 4401 0800 2758 2898 0800 4500
        0x0010:  0088 bddc 4000 4032 538b 0a0a 0a65 0a0a
        0x0020:  0a64 c082 47f5 0000 0002 7a2b 37d7 160c
        0x0030:  853c 870d 1119 5a34 9d95 e597 be6a 8bc7
        0x0040:  2037 a1f7 ba02 1ef2 a0be de5e 5406 a5b1
        0x0050:  0e03 c463 c235 5c45 9b51 6734 1f28 e364
        0x0060:  2b36 470b 64da bfa3 1a68 f209 94aa 44b0
        0x0070:  9131 ffe0 12f1 9208 3a7b aa95 da51 bafd
        0x0080:  31cd 3d0a 8733 56e0 ae0d d7b5 13fe 8c5e
        0x0090:  96d8 598d a74f
这是我的打印变量

original payload(88): 
    0x0000:  870d 1119 5a34 9d95 e597 be6a 8bc7 2037 
    0x0010:  a1f7 ba02 1ef2 a0be de5e 5406 a5b1 0e03 
    0x0020:  c463 c235 5c45 9b51 6734 1f28 e364 2b36 
    0x0030:  470b 64da bfa3 1a68 f209 94aa 44b0 9131 
    0x0040:  ffe0 12f1 9208 3a7b aa95 da51 bafd 31cd 
    0x0050:  3d0a 8733 56e0 ae0d 
key(16): 
    0x0000:  1a0f cccc 0315 2b58 1b1a 02ea 3664 485f 
iv(8): 
    0x0000:  7a2b 37d7 160c 853c 
icv(12): 
    0x0000:  d7b5 13fe 8c5e 96d8 598d a74f 
aad(8): 
    0x0000:  c082 47f5 0000 0002 
decrypted_payload(88): 
    0x0000:  860c 9110 87c6 db5a c40a a592 f862 b8ea 
    0x0010:  b476 3be6 0881 06d4 ad11 eb2a 2e1c 698d 
    0x0020:  a803 2417 8ffb 7130 444d 4fc8 b402 c602 
    0x0030:  1a0b 031b b89a 4ddb 707b f920 04ea 48c5 
    0x0040:  5424 5a9b bb34 a88a 08ee 2556 5532 3419 
    0x0050:  2621 19e6 f4e1 72b2 
Tag Verify Failed!
解密的有效负载应该是某个ICMP数据包。但这是错误的! 解密方法是否错误,或者变量是否错误地进入数据包?

  • 如果当前的8字节IV(ESP-IV,见下文)为:

    替换为以下12字节IV(Nonce/AES-GCM-IV,见下文):

  • 解密的消息是:

    45 00 00 54 8e 07 40 00 40 01 82 da 0a 00 0b 64 
    0a 00 0a 64 08 00 04 f2 28 7d 00 01 ed 10 0b 5d 
    00 00 00 00 0e 4f 05 00 00 00 00 00 10 11 12 13
    14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23
    24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33
    34 35 36 37 01 02 02 04
    
  • 说明:根据第8.1节的说明,AES-128-GCM-ESP的密钥有20个字节。前16个字节是AES-128-GCM密钥,最后4个字节是salt。nonce由salt(4字节)和ESP-IV(8字节)组成,因此大小为12字节。当前值为AES-GCM-IV。有关ESP-IV和AES-GCM-IV之间差异的解释,请参见第2节。在当前代码中,ESP-IV用作AES-GCM-IV,这是错误的。如果nonce用作AES-GCM-IV,则解密成功

  • salt的4个字节可以强制执行以下操作:

    b3 0d e6 26
    
    它们应与20字节AES-128-GCM-ESP密钥的最后4个字节相对应

  • \u aes\u gcm\u decrypt
    -方法包含一个小缺陷,但在gcm模式下不会产生任何后果。然而,该方法应修改如下:

    ...
    EVP_DecryptUpdate(ctx, outbuf, &outlen, payload, payload_len);
    int plaintext_len = outlen;                                    // added
    
    EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, icv_len, icv);
    
    rv = EVP_DecryptFinal_ex(ctx, outbuf + outlen, &outlen);       // modified
    plaintext_len += outlen;                                       // added
    ...
    
    明文\u len
    中存储解密消息的长度。启用填充时解密可能最后一个未完全填充的块。由于GCM模式不使用填充,因此错误不起作用。但是,存储在
    outlen
    中的解密消息的长度在当前代码中丢失,另请参阅


当前示例的4字节salt是什么样子的?
b3 0d e6 26
...
EVP_DecryptUpdate(ctx, outbuf, &outlen, payload, payload_len);
int plaintext_len = outlen;                                    // added

EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, icv_len, icv);

rv = EVP_DecryptFinal_ex(ctx, outbuf + outlen, &outlen);       // modified
plaintext_len += outlen;                                       // added
...