【发布时间】:2021-11-12 11:56:36
【问题描述】:
Release notes 用于 Bouncycastle 版本:1.69(2021 年 6 月 7 日)状态:
SP 800-38G 中两种 FPE 算法 FF1 和 FF3-1 的实现已添加到轻量级 API 和 JCE 提供程序中。
这些可以在bcprov-jdk15onJAR 中找到。
这是尝试使用它的代码:
import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.crypto.AlphabetMapper;
import org.bouncycastle.crypto.util.BasicAlphabetMapper;
import org.bouncycastle.jcajce.spec.FPEParameterSpec;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.testng.annotations.Test;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
@Slf4j
public class AesFpe {
@Test
public void testAesFpe() throws Exception {
SecretKey key = generateKey();
byte[] tweak = getTweak();
int radix = getRadix("0123456789");
Charset encoding = StandardCharsets.UTF_8;
byte[] plaintext = "510123456".getBytes(encoding);
Cipher cipher = Cipher.getInstance("AES/FF3-1/NoPadding", new BouncyCastleProvider());
byte[] ciphertext = encrypt(cipher, key, tweak, radix, plaintext);
log.info("Ciphertext: {}", new String(ciphertext));
byte[] decrypted = decrypt(cipher, key, tweak, radix, ciphertext);
assertThat(decrypted, equalTo(plaintext));
}
public 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 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 SecretKey generateKey() throws NoSuchAlgorithmException {
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
int keyLength = 256;
keyGenerator.init(keyLength);
return keyGenerator.generateKey();
}
private byte[] getTweak() {
int tweakLength = 7;
byte[] tweak = new byte[tweakLength];
new SecureRandom().nextBytes(tweak);
return tweak;
}
private int getRadix(String alphabet) {
AlphabetMapper alphabetMapper = new BasicAlphabetMapper(alphabet);
int radix = alphabetMapper.getRadix();
log.info("Radix: {}", radix);
return radix;
}
}
我还没有遇到如何正确使用它的示例。问题似乎与基数有关。使用以下堆栈跟踪执行上述结果:
java.lang.IllegalArgumentException: input data outside of radix
at org.bouncycastle.crypto.fpe.SP80038G.checkData(Unknown Source)
at org.bouncycastle.crypto.fpe.SP80038G.checkArgs(Unknown Source)
at org.bouncycastle.crypto.fpe.SP80038G.encryptFF3_1(Unknown Source)
at org.bouncycastle.crypto.fpe.FPEFF3_1Engine.encryptBlock(Unknown Source)
at org.bouncycastle.crypto.fpe.FPEEngine.processBlock(Unknown Source)
at org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher$BufferedFPEBlockCipher.doFinal(Unknown Source)
at org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher.engineDoFinal(Unknown Source)
at javax.crypto.Cipher.doFinal(Cipher.java:2164)
基数设置为例如64 或更高版本此代码有效,但这不再是 FPE - 密文包含 [0-9] 范围之外的字符。如何解决?
【问题讨论】:
标签: java encryption cryptography bouncycastle encryption-symmetric