没有外部库的要求将列表缩减为 DES、3DES 和 AES。 DES 和 3DES 的块大小为 64 位,而 AES 的块大小为 128 位。有不同的方面,可以检查一下。
密文大小
DES 和 3DES 最适合用于最多 56 位宽(非全长)的整数,因为由于填充,结果将是 8 字节的单个块。如果您加密一个完整的长值,则会添加一个额外的填充块。
AES 将始终为任何长整型值生成 16 字节密文。
速度
根据this analysis,AES (Rijndael-128) 的速度是 DES/3DES 的两倍多,并且密钥大小更大(更安全)。当 CPU 支持 AES-NI 时,AES 甚至可以比 DES 或 3DES 快得多。当前所有的 CPU 都支持这一点。这是我当前从openssl speed 命令获取的结果。
AES 对 16 字节有效负载达到 127MB/s,而 3DES 仅达到 27MB/s。 Here 是要查找的数据。
安全
不要将 DES 用于任何严重的事情,因为它只有一个 56 位密钥(64 位奇偶校验)。暴力破解成本为 256。 3DES 也不是很好,因为暴力破解成本是2112。 AES 的暴力破解成本为 2128、2192、2256,具体取决于使用的密钥大小。
代码
可能使用 AES:
private final String CIPHER_NAME = "AES/ECB/PKCS5Padding";
private final String ALGORITHM_NAME = "AES"; // keySizes 128, 192, 256
// private final String CIPHER_NAME = "DES/ECB/PKCS5Padding";
// private final String ALGORITHM_NAME = "DES"; // keySize 56
// private final String CIPHER_NAME = "DESede/ECB/PKCS5Padding";
// private final String ALGORITHM_NAME = "DESede"; // keySize 168
byte[] encrypt(SecretKey key, long num) {
BigInteger bignum = BigInteger.valueOf(num);
Cipher cipher = Cipher.getInstance(CIPHER_NAME);
cipher.init(Cipher.ENCRYPT_MODE, key);
return cipher.doFinal(bignum.toByteArray());
}
long decrypt(SecretKey key, byte[] ct) {
Cipher cipher = Cipher.getInstance(CIPHER_NAME);
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] pt = cipher.doFinal(ct);
BigInteger bignum = new BigInteger(pt);
return bignum.longValue();
}
SecretKey keyGen(String algorithm, int keySize) {
KeyGenerator keygen = KeyGenerator.getInstance(algorithm);
keygen.init(keySize);
return keygen.generateKey();
}
操作模式
这里我使用 ECB 模式。使用它通常不是一个好主意。它有一个问题,即用相同的密钥加密相同的明文会导致相同的密文。这可能不是可接受的属性。如果它不可接受,那么您需要使用例如带有新随机 IV 的 CBC 模式。 With 会将密文炸毁一个额外的块。