Java 即使输入弹簧长度变化,也会以固定长度生成AES加密输出结果
我有一个名为user.com的表,它有一个列 名字叫瓦查尔(25) 当使用AES算法插入时,Im加密名字值。(AES/CBC/PKCS5P) 但每次加密firstname值时,我都不会得到相同长度的输出值(加密)。当firstname值字符串长度变化时,加密的输出长度不适合为列定义的varchar lenth 字符串输入=“测试”; //加密值:978fbfa24962827da56b1f00896a4f2cbfc25b744e836c2a22d4292fb16dd53a 字符串输入=“这是测试”; //加密值:978fbfa24962827da56b1f00896a4f2cbfc25b744e836c22a22d4292fb16dd53aa22d4292fb16dd53a 我得到以下例外 数据截断:数据对列太长 我在这里添加了我的代码Java 即使输入弹簧长度变化,也会以固定长度生成AES加密输出结果,java,mysql,encryption,Java,Mysql,Encryption,我有一个名为user.com的表,它有一个列 名字叫瓦查尔(25) 当使用AES算法插入时,Im加密名字值。(AES/CBC/PKCS5P) 但每次加密firstname值时,我都不会得到相同长度的输出值(加密)。当firstname值字符串长度变化时,加密的输出长度不适合为列定义的varchar lenth 字符串输入=“测试”; //加密值:978fbfa24962827da56b1f00896a4f2cbfc25b744e836c2a22d4292fb16dd53a 字符串输入=“这是测试
public String encrypt(String plainText) {
byte[] cipherBytes = null;
log.info("Started encryption...");
if (plainText != null && !plainText.isEmpty()) {
if (cipher != null && key != null) {
try {
byte[] ivByte = new byte[cipher.getBlockSize()];
IvParameterSpec ivParamsSpec = new IvParameterSpec(ivByte);
cipher.init(Cipher.ENCRYPT_MODE, key, ivParamsSpec);
cipherBytes = cipher.doFinal(plainText.getBytes());
plainText = Hex.encodeHexString(cipherBytes);
log.info("Completed encryption.");
log.info("Encrypted data : "
+ new String(cipherBytes, "UTF8"));
} catch (BadPaddingException | IllegalBlockSizeException
| InvalidKeyException
| InvalidAlgorithmParameterException
| UnsupportedEncodingException e) {
log.error("Encryption failed : " + e.getMessage());
e.printStackTrace();
throw new RuntimeException("Encryption failed : "
+ e.getMessage());
}
} else {
log.error("Encryption failed, cipher, key is null.");
throw new RuntimeException(
"Encryption failed, cipher, key is null.");
}
} else {
return plainText;
}
return plainText;
}
public String decrypt(String cipherHexString) throws AuthorizationException {
log.info("Started decryption...");
byte[] plainTextBytes = null;
String resource = "kk";
String resourceCatagory = "kk tables";
String accessType = "write";
try {
if (decryptionAuthorizer.authorize(resource, resourceCatagory,
accessType)) {
if (cipherHexString != null && !cipherHexString.isEmpty()) {
if (cipher != null && key != null) {
try {
byte[] ivByte = new byte[cipher.getBlockSize()];
IvParameterSpec ivParamsSpec = new IvParameterSpec(
ivByte);
cipher.init(Cipher.DECRYPT_MODE, key, ivParamsSpec);
plainTextBytes = cipher.doFinal(Hex
.decodeHex(cipherHexString.toCharArray()));
cipherHexString = new String(plainTextBytes);
log.info("Completed decryption.");
} catch (InvalidKeyException
| InvalidAlgorithmParameterException
| IllegalBlockSizeException
| BadPaddingException | DecoderException e) {
log.error("Decryption failed : " + e.getMessage());
e.printStackTrace();
throw new RuntimeException("Decryption failed : "
+ e.getMessage());
}
} else {
log.error("Decryption failed, cipher, key is null.");
throw new RuntimeException(
"Decryption failed, cipher, key is null.");
}
} else {
return cipherHexString;
}
}
} catch (AuthorizationException e) {
throw new AuthorizationException(
"User not authorized to decrypt data.");
}
return cipherHexString;
}
/**
* This method is used to manually override max key length permission, as an
* application level solution instead of configuration changes in
* security.policy.
*/
private void fixKeyLength() {
String errorString = "Failed manually overriding key-length permissions.";
int newMaxKeyLength;
try {
newMaxKeyLength = javax.crypto.Cipher.getMaxAllowedKeyLength("AES");
log.info("Initial max key size for AES : " + newMaxKeyLength);
if (newMaxKeyLength < 256) {
Class c = Class
.forName("javax.crypto.CryptoAllPermissionCollection");
Constructor con = c.getDeclaredConstructor();
con.setAccessible(true);
Object allPermissionCollection = con.newInstance();
Field f = c.getDeclaredField("all_allowed");
f.setAccessible(true);
f.setBoolean(allPermissionCollection, true);
c = Class.forName("javax.crypto.CryptoPermissions");
con = c.getDeclaredConstructor();
con.setAccessible(true);
Object allPermissions = con.newInstance();
f = c.getDeclaredField("perms");
f.setAccessible(true);
((Map) f.get(allPermissions)).put("*", allPermissionCollection);
c = Class.forName("javax.crypto.JceSecurityManager");
f = c.getDeclaredField("defaultPolicy");
f.setAccessible(true);
Field mf = Field.class.getDeclaredField("modifiers");
mf.setAccessible(true);
mf.setInt(f, f.getModifiers() & ~Modifier.FINAL);
f.set(null, allPermissions);
newMaxKeyLength = Cipher.getMaxAllowedKeyLength("AES");
log.info("Max key size permission changed, new max key size for AES : "
+ newMaxKeyLength);
}
} catch (Exception e) {
throw new RuntimeException(errorString, e);
}
if (newMaxKeyLength < 256)
throw new RuntimeException(errorString);
}
public String getAlgo() {
return algo;
}
public void setAlgo(String algo) {
this.algo = algo;
}
public String getKeyAlias() {
return keyAlias;
}
公共字符串加密(字符串明文){
字节[]cipherBytes=null;
log.info(“已开始加密…”);
if(plainText!=null&!plainText.isEmpty()){
if(cipher!=null&&key!=null){
试一试{
byte[]ivByte=新字节[cipher.getBlockSize()];
IvParameterSpec ivParamsSpec=新的IvParameterSpec(ivByte);
cipher.init(cipher.ENCRYPT_模式,密钥,ivParamsSpec);
cipherBytes=cipher.doFinal(明文.getBytes());
明文=十六进制编码十六进制字符串(cipherBytes);
log.info(“已完成加密”);
log.info(“加密数据:”
+新字符串(cipherBytes,“UTF8”);
}catch(BadPaddingException | IllegalBlockSizeException
|InvalidKeyException
|无效算法参数异常
|不支持的编码异常(e){
错误(“加密失败:+e.getMessage());
e、 printStackTrace();
抛出新的运行时异常(“加密失败:”
+e.getMessage());
}
}否则{
错误(“加密失败,密码,密钥为空。”);
抛出新的运行时异常(
“加密失败,密码,密钥为空。”);
}
}否则{
返回纯文本;
}
返回纯文本;
}
公共字符串解密(String cipherHexString)引发AuthorizationException{
log.info(“已开始解密…”);
字节[]明文字节=null;
String resource=“kk”;
String resourceCatagory=“kk tables”;
String accessType=“write”;
试一试{
if(decryptionAuthorizer.authorize)(资源,资源分类,
存取类型){
if(cipherHexString!=null&!cipherHexString.isEmpty()){
if(cipher!=null&&key!=null){
试一试{
byte[]ivByte=新字节[cipher.getBlockSize()];
IvParameterSpec ivParamsSpec=新的IvParameterSpec(
ivByte);
cipher.init(cipher.DECRYPT_模式,密钥,ivParamsSpec);
plainTextBytes=cipher.doFinal(十六进制)
.decodeHex(cipherHexString.toCharArray());
cipherHexString=新字符串(明文字节);
log.info(“已完成解密”);
}捕获(InvalidKeyException)
|无效算法参数异常
|非法块大小异常
|BadPaddingException(解码异常){
错误(“解密失败:+e.getMessage());
e、 printStackTrace();
抛出新的RuntimeException(“解密失败:”
+e.getMessage());
}
}否则{
错误(“解密失败,密码,密钥为空。”);
抛出新的运行时异常(
“解密失败,密码,密钥为空。”);
}
}否则{
返回密码字符串;
}
}
}捕获(授权异常e){
抛出新的AuthorizationException(
“未授权用户解密数据。”);
}
返回密码字符串;
}
/**
*此方法用于手动覆盖“最大密钥长度”权限,作为
*应用程序级解决方案,而不是中的配置更改
*安全政策。
*/
私有void fixKeyLength(){
String errorString=“手动覆盖密钥长度权限失败。”;
int newMaxKeyLength;
试一试{
newMaxKeyLength=javax.crypto.Cipher.getMaxAllowedKeyLength(“AES”);
log.info(“AES的初始最大密钥大小:”+newMaxKeyLength);
如果(newMaxKeyLength<256){
c类=c类
.forName(“javax.crypto.CryptoAllPermissionCollection”);
构造函数con=c.getDeclaredConstructor();
con.setAccessible(true);
对象allPermissionCollection=con.newInstance();
字段f=c.getDeclaredField(“允许所有”);
f、 setAccessible(true);
f、 setBoolean(allPermissionCollection,true);
c=Class.forName(“javax.crypto.CryptoPermissions”);
con=c.getDeclaredConstructor();
con.setAccessible(true);
Object allPermissions=con.newInstance();
f=c.getDeclaredField(“perms”);
f、 setAccessible(true);
varchar("test") -> 8 bytes long -> 16 bytes hex string -> 32 bytes after encrypting (with padding) -> 64 bytes hex string
varchar("test is test") -> 24 bytes long -> 48 bytes hex string -> 64 bytes after encrypting (with padding) -> 128 bytes hex string