What is in Java a cipher function for integer encryption having these properties?:
You should never implement a cipher yourself if you want any security. There's just too much what can get wrong.
But you can write your numbers into a byte[]
and use a cipher provided with Java like described in this answer.
If you don't need a secure solution, but just fast one, consider the XOR cipher:
int key = ...
....
int b = a ^ key;
int c = b ^ key;
assert (c == a);
The requirement for no external library reduces the list to DES, 3DES and AES. DES and 3DES have a block size of 64 bits whereas AES has a block size of 128 bits. There are different aspects, one can examine this for.
DES and 3DES are best used for integers that are at most 56-bit wide (non-full long), because the result will be a single block of 8 byte, because of padding. If you encrypt a full long value, then an additional padding block will be added.
AES will always produce a 16 byte ciphertext for any int of long value.
According to this analysis AES (Rijndael-128) is more than twice as fast as DES/3DES with a bigger key size (more secure). AES can be even much faster than DES or 3DES when the CPU supports AES-NI. All current CPUs support this. This is my current result for taken from the openssl speed
command.
AES achieves 127MB/s for 16 byte payloads whereas 3DES only achieves 27MB/s. Here's the data to poke around.
Don't use DES for anything serious, because it only has a 56-bit key (64-bit with parity). Brute forcing cost is 256. 3DES is also not that good, because Brute forcing cost is 2112. Brute forcing cost for AES is 2128, 2192, 2256 depending on the used key size.
Probably use 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();
}
Here I use ECB mode. It is generally not a good idea to use it. It has a problem that encrypting the same plaintext with the same key results in the same ciphertext. This may not be a property that is acceptable. If it is not acceptable, then you need to use for example CBC mode with a new random IV. With will blow up the ciphertext by an additional block.