Chacha20
承接上文,这篇专门研究研究逆向里面,chacha20的识别与逆向。
识别
一般在进行chacha20加密之前,都会进行chacha20的初始化
初始化流程如下
- 设置初始常量:将固定的字符串”expand 32-byte k”转换成4个32位无符号整数作为初始常量。
- 设置密钥和计数器:将128位的密钥和64位的计数器分别存储到状态矩阵的指定位置。
- 设置nonce:将96位的nonce(一次性数字)存储到状态矩阵的指定位置。
- 复制状态矩阵:将初始状态矩阵复制到工作状态矩阵,后续加密操作会在工作状态矩阵上进行。
cpp那个题目里面我们识别不出因为,实在太难以辨认了,就这么个东西跑出来谁能看的懂呢。

但是放进汇编里面,跑一跑就可以看到,他们实际上确实再往一个东西写东西

这是初始化const
然后一个一个读入我们的明文,比较让我感觉难受的是,他读入的过程没有循环,也没有jmp,导致我刚开始看的时候如果找不到hex窗口的内容,也很难进行分析。

逆向
还是要学学chacha20的原理
主要是借助了一位师傅的博客
https://blog.csdn.net/choumin/article/details/132804784#:~:text=chacha20,%E7%AE%97%E6%B3%95%E7%9A%84%E5%9F%BA%E6%9C%AC%E6%80%9D%E6%83%B3%EF%BC%9A%E5%8A%A0%E5%AF%86%E6%97%B6%EF%BC%8C%E5%B0%86%E6%98%8E%E6%96%87%E6%95%B0%E6%8D%AE%E4%B8%8E%E7%94%A8%E6%88%B7%E4%B9%8B%E9%97%B4%E7%BA%A6%E5%AE%9A%E7%9A%84%E6%9F%90%E4%BA%9B%E6%95%B0%E6%8D%AE%E8%BF%9B%E8%A1%8C%E5%BC%82%E6%88%96%E6%93%8D%E4%BD%9C%EF%BC%8C%E5%BE%97%E5%88%B0%E5%AF%86%E6%96%87%E6%95%B0%E6%8D%AE%EF%BC%9B%E7%94%B1%E5%BC%82%E6%88%96%E6%93%8D%E4%BD%9C%E7%9A%84%E7%89%B9%E7%82%B9%E5%8F%AF%E7%9F%A5%EF%BC%8C%E5%9C%A8%E8%A7%A3%E5%AF%86%E6%97%B6%EF%BC%8C%E5%8F%AA%E9%9C%80%E8%A6%81%E5%B0%86%E5%AF%86%E6%96%87%E6%95%B0%E6%8D%AE%E4%B8%8E%E7%94%A8%E6%88%B7%E4%B9%8B%E9%97%B4%E7%BA%A6%E5%AE%9A%E7%9A%84%E9%82%A3%E4%BA%9B%E6%95%B0%E6%8D%AE%E5%86%8D%E6%AC%A1%E8%BF%9B%E8%A1%8C%E5%BC%82%E6%88%96%E6%93%8D%E4%BD%9C%EF%BC%8C%E5%B0%B1%E5%BE%97%E5%88%B0%E4%BA%86%E6%98%8E%E6%96%87%E6%95%B0%E6%8D%AE%E3%80%82
从原理上来讲,其实作为对称加密算法的chacha20并不难理解,明文异或key成密文,密文异或key回去就是明文,作为逆向的一环,重要的就是找到是什么去和明文异或,这也是这个算法复杂的地方。
如果明文很长,超过64字节的话,就需要分为n个64位的分组,然后每一种都有个对应的key_n这个key_n根据key_init经过某种计算生成出来。
我们目前就一个分组,就不用去关心这种计算了。
而最开始的keyinit,如下产生


一共64个bit。
然后是轮的概念
这是四分之一轮

整个一轮

整个流程就是先进行如上4个四分之一轮的列运算,再进行如上4个四分之一轮的对角线运算,然后将这两轮进行十遍。
简单来讲,四个四分之一组成了一个列运算,另外四个四分之组成一个对角线运算,然后两个运算一组跑十次,一共二十次运算,这也就是chacha20的20来处。
举例


上面那个博客的师傅例子举得很好,我就不摆弄了。
再回到我们那个题目,其实作为流密码,重要的是再每一轮的轮加密的密钥流dump下来所生成的密钥,然后去和密文异或。这也是我总结出来的这一类题目初步的想法。