比特与字节
比特(bit):计算机中最小的数据单位,值为 0 或 1。
字节(byte):8 个比特组成一个字节,范围 0~255(即 0x00~0xFF)。
密码学算法本质上都是对比特/字节的操作。理解位操作是理解密码算法实现的基础。
基本位操作
| 操作 | 符号 | 说明 | 例子(8位) |
|---|---|---|---|
| AND | & | 两位都为1才为1 | 1100 & 1010 = 1000 |
| OR | | | 任一位为1则为1 | 1100 | 1010 = 1110 |
| XOR | ^ | 不同为1,相同为0 | 1100 ^ 1010 = 0110 |
| NOT | ~ | 按位取反 | ~1100 = 0011 |
| 左移 | << | 所有位左移,低位补0 | 1010 << 2 = 101000 |
| 右移 | >> | 所有位右移,高位补0 | 1010 >> 2 = 0010 |
XOR 在密码学中的特殊地位
XOR(异或)是密码学中最核心的位操作,原因:
- 自反性:a ^ a = 0(任何数与自身异或结果为 0)
- 恒等性:a ^ 0 = a(任何数与 0 异或不变)
- 可逆性:若 c = a ^ b,则 a = c ^ b 且 b = c ^ a
- 交换律和结合律:a ^ b = b ^ a;(a ^ b) ^ c = a ^ (b ^ c)
这些性质使得 XOR 天然适合加密解密:加密 c = m ^ k,解密 m = c ^ k。
一次性密码本(OTP)、流密码(RC4、ChaCha20)、分组密码的多种工作模式都依赖 XOR。
字节序(Endianness)
多字节数据在内存中的存储顺序称为字节序:
- 大端序(Big-Endian):高位字节在前(低地址)。如 0x12345678 存为 12 34 56 78。
- 小端序(Little-Endian):低位字节在前(低地址)。如 0x12345678 存为 78 56 34 12。
| 值 | 大端序 | 小端序 |
|---|---|---|
| 0x01020304 | 01 02 03 04 | 04 03 02 01 |
| 0xAABBCCDD | AA BB CC DD | DD CC BB AA |
密码学中的字节序
不同算法和标准使用不同的字节序,这是实现时常见的 bug 来源:
- MD5:小端序
- SHA-1/SHA-2:大端序
- SHA-3:小端序
- AES:与平台无关,按字节处理
- RSA:大端序(PKCS#1 标准)
数据表示
密码学中常见的数据表示方式:
- 十六进制(Hex):每字节用两个十六进制字符表示,如 0xFF = 255。最常用的可读表示。
- Base64:用 64 个可打印字符编码任意二进制数据,3 字节 → 4 字符,常用于传输。
- Base58:Base64 去掉了易混淆字符(0/O, 1/l/I),比特币地址使用。
填充(Padding)
分组密码要求数据长度是块大小的整数倍(AES 为 16 字节),不足时需要填充:
- PKCS#7:缺 n 字节就填充 n 个值为 n 的字节。如缺 3 字节则填 03 03 03。若恰好满块则加一个完整块的填充。
- Zero Padding:填 0x00 字节,但无法区分原始数据末尾的 0 和填充的 0。
- ISO 7816-4:填 0x80 后跟若干 0x00,可以唯一确定填充边界。