Skip to content

Instantly share code, notes, and snippets.

@MrCoder
Created March 16, 2023 04:45
Show Gist options
  • Save MrCoder/1ba65f111636d806b83561bc9fbb4f20 to your computer and use it in GitHub Desktop.
Save MrCoder/1ba65f111636d806b83561bc9fbb4f20 to your computer and use it in GitHub Desktop.
FPE in Java with BouncyCastle
package org.example;
import org.bouncycastle.crypto.AlphabetMapper;
import org.bouncycastle.crypto.util.BasicAlphabetMapper;
import org.bouncycastle.jcajce.spec.FPEParameterSpec;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec;
import java.text.SimpleDateFormat;
import java.util.Arrays;
/**
* Hello world!
*
*/
public class App
{
// explain the following code
public static void main( String[] args ) throws Exception {
SecretKey key = generateAESKey("12345678901234567890123456789012");
byte[] tweak = getTweak();
AlphabetMapper alphabetMapper = new BasicAlphabetMapper("0123456789");
int radix = alphabetMapper.getRadix();
char[] plaintext = "123456788".toCharArray();
byte[] plain_bytes = alphabetMapper.convertToIndexes(plaintext);
Cipher cipher = Cipher.getInstance("AES/FF3-1/NoPadding", new BouncyCastleProvider());
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
System.out.println(sdf.format(System.currentTimeMillis()));
byte[] cipher_bytes = null;
for(int i = 0; i < 100000; i++) {
cipher_bytes = encrypt(cipher, key, tweak, radix, plain_bytes);
}
System.out.println(sdf.format(System.currentTimeMillis()));
byte[] decrypted = null;Fo
for(int i = 0; i < 100000; i++) {
decrypted = decrypt(cipher, key, tweak, radix, cipher_bytes);
}
System.out.println(sdf.format(System.currentTimeMillis()));
char[] cipher_chars = alphabetMapper.convertToChars(cipher_bytes);
System.out.println(new String(cipher_chars));
char[] plain_chars = alphabetMapper.convertToChars(decrypted);
System.out.println(new String(plain_chars));
System.out.println( "Hello World!" );
}
public static SecretKeySpec generateAESKey(String password) throws Exception {
// Convert password to bytes
byte[] passwordBytes = password.getBytes("UTF-8");
System.out.println("passwordBytes: " + passwordBytes.length);
// Generate 256-bit key from password bytes using SHA-256 hash function
MessageDigest sha = MessageDigest.getInstance("SHA-256");
byte[] keyBytes = sha.digest(passwordBytes); // will create a 32-byte key
// Truncate key to 128 bits (16 bytes) for use with AES
keyBytes = Arrays.copyOf(keyBytes, 32);
// Create secret key spec from AES key bytes
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
return keySpec;
}
public static byte[] encrypt(Cipher cipher, SecretKey key, byte[] tweak, int radix, byte[] plaintext) throws Exception {
AlgorithmParameterSpec fpeParameterSpec = new FPEParameterSpec(radix, tweak);
cipher.init(Cipher.ENCRYPT_MODE, key, fpeParameterSpec);
return cipher.doFinal(plaintext);
}
public static byte[] decrypt(Cipher cipher, SecretKey key, byte[] tweak, int radix, byte[] ciphertext) throws Exception {
AlgorithmParameterSpec fpeParameterSpec = new FPEParameterSpec(radix, tweak);
cipher.init(Cipher.DECRYPT_MODE, key, fpeParameterSpec);
return cipher.doFinal(ciphertext);
}
private static SecretKey generateKey() throws NoSuchAlgorithmException {
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
int keyLength = 256;
keyGenerator.init(keyLength);
return keyGenerator.generateKey();
}
private static byte[] getTweak() {
byte[] byteArray = new byte[7];
for (int i = 0; i < 7; i++) {
byteArray[i] = 0;
}
return byteArray;
}
private int getRadix(String alphabet) {
AlphabetMapper alphabetMapper = new BasicAlphabetMapper(alphabet);
int radix = alphabetMapper.getRadix();
return radix;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment