流密码
英文: Stream cipher.
别名: State cipher.
一次性密码本 (One-time pad, OTP)
一致性方程:
密钥 k 的长度和明文相等.
template <std::size_t N>
std::bitset<N> E(const std::bitset<N>& key, const std::bitset<N>& plaintext) {
return key ^ plaintext;
}
一次性
假设使用同一个密钥加密了两份密文:
只要截获了两份密文, 即可通过异或的交换律/归零律和恒等律可以得出对应明文异或的结果. 因此 OTP 的密钥只能使用一次.
优点
OTP 满足以下条件则无法破译:
- 密钥 k 的长度至少和明文相等.
- 密钥是在密钥空间中均匀分布的真随机数.
- 密钥不能自重复.
- 密钥不可能泄露.
完善保密性 (Prefect secrecy)
密文不应该揭露任何明文的信息.
缺点
因为
流密码
OTP 虽然具有完善保密性, 但在及时的网络通信中不实用, 因为密钥的长度大于或等于明文, 因此加密没有意义.
流密码在 OTP 的基础上进行了一些改动, 用安全性换取实用性.
伪随机数生成器 (Pseudorandom generators, PRG)
为了使 OTP 更具实用性, 可以将较短长度的密钥通过 PRG 拓展成和密文一样长的拓展后的密钥.
伪随机数生成器应该是不可预测的, 否则可以通过其中一段明文和密文得出密钥的一部分, 然后预测密钥的其他部分.
如线性同余随机数生成器 (Linear congruential generator), 虽然在统计学上具有良好的性质, 但容易预测.
// 先将 N 位的密钥拓展至 M 位, 然后再使用 OTP 进行加密
template <typename PRNG, std::size_t N, std::size_t M>
std::bitset<M> E(const std::bitset<N>& key, const std::bitset<M>& plaintext) {
static_assert(N < M, "");
std::bitset<M> extended_key;
PRNG engine(key.to_ulong());
for (std::size_t size = 0; size < M;
size += sizeof(typename PRNG::result_type) * sizeof(unsigned char)) {
extended_key |= engine() << size;
}
return E(extended_key, plaintext);
}