自制加密通信协议(一):对称加密算法

自古以来,有大量信息需要隐秘地传输,例如军事机密。密码学也随之发展起来。一种常用的加密算法是对称加密算法,它由加密函数E和解密函数D构成:

    C=E(T,K)
    T=D(C,K)

其中T为明文,C为密文。信息的传输双方事先约定一个共用的密钥K。密文可以在不安全的信道中传递,即使被敌人截获,在未知密码的情况下也很难恢复出原文。

ChaCha20 算法

我尝试使用名为 ChaCha20 的算法来处理互联网上传输的信息。该算法的详细描述可以参阅 RFC 8439。 ChaCha20 使用的核心部分是由 16 个 32 位整数构成的状态:

 0  1  2  3
 4  5  6  7
 8  9 10 11
12 13 14 15

之后用一种“四分之一轮” (quarter round) 算法 QR 来操作这个状态:

QR(a, b, c, d) ::
    a += b; d ^= a; d <<= 16;
    c += d; b ^= c; b <<= 12;
    a += b; d ^= a; d <<= 8;
    c += d; b ^= c; b <<= 7;

一“轮”由 4 个“四分之一轮”构成, 奇数轮为:

QR(0, 4,  8, 12);
QR(1, 5,  9, 13);
QR(2, 6, 10, 14);
QR(3, 7, 11, 15);

即对每列执行 QR 操作。 偶数轮为:

QR(0, 5, 10, 15);
QR(1, 6, 11, 12);
QR(2, 7,  8, 13);
QR(3, 4,  9, 14);

即沿着主对角线的方向执行 QR 操作。

初始时,0-3 是常数 expand 32-byte k (共 16 字节),4-11 是密钥 K(共 32 字节),12 是计数器 B, 13-15 是一次性随机数 N (nonce):

cccccccc cccccccc cccccccc cccccccc
kkkkkkkk kkkkkkkk kkkkkkkk kkkkkkkk
kkkkkkkk kkkkkkkk kkkkkkkk kkkkkkkk
bbbbbbbb nnnnnnnn nnnnnnnn nnnnnnnn

运行一次 ChaCha20 算法执行 20 “轮”, 即 80 次 QR 操作,然后再和初始状态逐位相加(目的是使计算过程不可逆)。这样得到的的状态和明文(密文)逐位异或,就得到了密文(明文)。注意,解密过程和加密过程完全等价。

这样的计算一次只能处理 64 字节的明文。每处理 64 字节的明文,计数器 B 自加一。这样,每次用于异或的状态都不相同。

给每个明文加密应采用不同的一次性随机数,理由类似。一次性随机数应当在双方通信时协商,可以采用明文方式发送。

密钥则应以其他的安全方式分享。例如,当面分享。也可以采用密钥交换算法(如 Diffie-Hellman)。


分享