在 Java 中快速、简单地使用对称密码进行整数加密

Fast, simple to use symmetric cipher for integer encryption in Java

Java 具有这些属性的整数加密的密码函数是什么?:

我只需要将它用于 encrypt/decrypt 个整数。

如果你想要 任何 安全,你永远不应该自己实施密码。可能出错的地方太多了。

但是您可以将数字写入 byte[] 并使用 Java 提供的密码,如 this answer 中所述。

没有外部库的要求将列表减少到 DES、3DES 和 AES。 DES 和 3DES 的块大小为 64 位,而 AES 的块大小为 128 位。有不同的方面,可以看这个。

密文大小

DES 和 3DES 最适用于最多 56 位宽(非全长)的整数,因为由于填充,结果将是一个 8 字节的块。如果您加密一个完整的 long 值,则会添加一个额外的填充块。

AES 将始终为任何 long 值的 int 生成 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 会将密文炸毁一个额外的块。

如果您不需要安全解决方案,而只需要快速,请考虑XOR cipher:

int key = ...
....
int b = a ^ key;
int c = b ^ key;
assert (c == a);