首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从ram中获取ChaCha20密钥

从ram中获取ChaCha20密钥
EN

Security用户
提问于 2016-06-16 18:03:03
回答 1查看 264关注 0票数 0

还有其他各种各样的帖子谈论从ram中获取密钥,例如

我的问题有点不同。假设我们有密钥,对于一个简短的窗口,我们将使用它初始化密码(在本例中是ChaCha20),然后从内存中删除密钥(使用最佳实践、memset_s等)*社论2。

一旦密码被初始化,这是否等同于在内存中有密钥?

具体来说,查看ChaCha20参考代码:https://cr.yp.to/streamciphers/timings/estreambench/submissions/salsa20/chacha8/ref/chacha.c

代码语言:javascript
复制
void ECRYPT_keysetup(ECRYPT_ctx *x,const u8 *k,u32 kbits,u32 ivbits)
{
  const char *constants;

  x->input[4] = U8TO32_LITTLE(k + 0);
  x->input[5] = U8TO32_LITTLE(k + 4);
  x->input[6] = U8TO32_LITTLE(k + 8);
  x->input[7] = U8TO32_LITTLE(k + 12);
  if (kbits == 256) { /* recommended */
    k += 16;
    constants = sigma;
  } else { /* kbits == 128 */
    constants = tau;
  }
  x->input[8] = U8TO32_LITTLE(k + 0);
  x->input[9] = U8TO32_LITTLE(k + 4);
  x->input[10] = U8TO32_LITTLE(k + 8);
  x->input[11] = U8TO32_LITTLE(k + 12);
  x->input[0] = U8TO32_LITTLE(constants + 0);
  x->input[1] = U8TO32_LITTLE(constants + 4);
  x->input[2] = U8TO32_LITTLE(constants + 8);
  x->input[3] = U8TO32_LITTLE(constants + 12);
}

看起来一个人只需要用x->输入指向内存位置,从那个点读取48字节的数据,你就可以得到它了。

  1. 这是正确的吗?
  2. 如何在软件中防止这种情况呢?(最佳做法)

编辑:我看到,至少输入12和输入13是调整的字节是运行.通过调整输入8和输入9,可以对密码进行“查找”。因此,只要简单地寻找一个随机的“位置”,并在初始化时加密一些随机填充字节就足够了。

  1. 这是正确的,它会提高防御抓取键(或初始化状态)吗?

编辑2:

我相信一旦密码被初始化,就可以从内存中删除密钥,因为引用实现不使用它来解密.还是我漏掉了什么?

示例:

代码语言:javascript
复制
ECRYPT_init();
ECRYPT_keysetup(&ctx, MyKey, ECRYPT_MAXKEYSIZE, ECRYPT_MAXIVSIZE);
ECRYPT_ivsetup(&ctx, MyIv);

//notice neither MyKey nor MyIv are used here:
ECRYPT_decrypt_bytes(&ctx, ciphertext, plaintext, ciphertext_len);
EN

回答 1

Security用户

回答已采纳

发布于 2016-06-17 08:11:52

ChaCha20算法非常简单,如果您对它的工作方式感到好奇,您可以编写自己的实现(但不要在生产中使用它!)RFC 7539是一个简单的参考,它还附带了示例,因此您可以在进行过程中轻松地检查正确性。但是,它的工作方式是将消息与作为一组64字节块生成的密钥流进行异或,其中每个块由三个参数“命名”:

  1. 钥匙(秘密);
  2. 现在(不是秘密);
  3. 块计数器(不是秘密的)。

使用这些值和一些常量,以代码段显示的方式初始化该块。然后,用双倍运算10次(10次双回合=20次,这就是为什么名字中有"20“)来搅乱这个块。现在,关键的是,块的初始状态被添加到结果中,这一步再次需要键--所以如果删除它,就无法执行最后一步。

在最后一次添加之后,密钥不应该很容易从结果块中恢复(否则密码就完全破坏了!)但是,该块的内容是一个敏感的秘密,因为看到它的攻击者可以解密相应的密文块。

然而,在这一点上,您所得到的只是一个64字节的块,它只对消息的一个64字节块进行加密或解密。除非64字节是您将加密过的最大消息长度,否则您将一次又一次地需要密钥来生成额外的块。因此,只有在加密或解密完整个消息后,才能擦除密钥和阻塞。

因为密钥块和密钥流块都是秘密数据,所以您需要使用操作系统的功能来防止内存被交换到磁盘。在你完成记忆之后,你会想要安全地把它调零。

类似的考虑也适用于其他密码,但细节不同。例如,许多密码器(但不是ChaCha20)都有密钥调度,即从秘密密钥派生的“子密钥”序列。通常情况是,在您生成密钥计划之后,您不再需要密钥了,因此您可以在此时将密钥调零,但是子键需要得到保护,并且您需要保存它们,因为您在处理的每个块中都重用它们。

票数 1
EN
页面原文内容由Security提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://security.stackexchange.com/questions/127255

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档