大佬教程收集整理的这篇文章主要介绍了Java AES加密和解密,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
如果对于块密码,您将不使用Cipher
包含填充方案的转换,则需要使明文中的字节数为该密码的块大小的整数倍。
因此,要么将纯文本填充到16字节的倍数(即AES块大小),要么在创建Cipher
对象时指定填充方案。例如,您可以使用:
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5padding");
除非您有充分的理由不这样做,否则请使用JCE实现中已包含的填充方案。他们考虑了许多微妙和极端的情况,否则您将不得不自己意识到和应对这些情况。
好的,您的第二个问题是您String
用来保存密文。
一般来说,
String s = new String(someBytes);
byte[] retrIEvedBytes = s.getBytes();
会 有someBytes
和retrIEvedBytes
是相同的。
如果您希望/必须将密文保存在中String
,请先对密文字节进行base64编码,然后String
从base64编码的字节中构造。然后,当您解密时,将从getBytes()
中获取base64编码的字节String
,然后对它们进行base64解码以获取真实的密文,然后对其进行解密。
出现此问题的原因是,大多数(全部?)字符编码都无法将任意字节映射到有效字符。因此,当您String
从密文创建密码时,String
构造函数(使用字符编码将字节转换为字符)本质上必须丢弃一些字节,因为它对它们毫无意义。因此,当您从字符串中获取字节时,它们与您放入字符串中的字节不同。
在Java(以及通常在现代编程中)中,除非绝对知道要处理ASCII,否则不能假定一个字符=一个字节。这就是为什么要从任意字节构建字符串时需要使用base64(或类似的东西)的原因。
我想使用128位AES加密和16字节密钥对密码进行加密和解密。javax.crypto.BadPaddingException
解密值时出现错误。解密时我丢失任何内容吗?
public static void main(String args[]) {
Test t = new Test();
String encrypt = new String(t.encrypt("mypassword"));
System.out.println("decrypted value:" + t.decrypt("ThisIsASecretKey",encrypt));
}
public String encrypt(String value) {
try {
byte[] raw = new byte[]{'T','h','i','s','I','A','S','e','c','r','t','K','y'};
SecretKeySpec skeySpec = new SecretKeySpec(raw,"AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE,skeySpec);
byte[] encrypted = cipher.doFinal(value.getBytes());
System.out.println("encrypted string:" + (new String(encrypted)));
return new String(skeySpec.getEncoded());
} catch (NoSuchAlgorithmException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE,null,ex);
} catch (IllegalBlockSizeException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE,ex);
} catch (BadPaddingException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE,ex);
} catch (InvalidKeyException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE,ex);
} catch (NoSuchPaddingException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE,ex);
}
return null;
}
public String decrypt(String key,String encrypted) {
try {
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(),"AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE,new SecretKeySpec(skeySpec.getEncoded(),"AES"));
//getting error here
byte[] original = cipher.doFinal(encrypted.getBytes());
return new String(original);
} catch (IllegalBlockSizeException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE,ex);
} catch (NoSuchAlgorithmException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE,ex);
}
return null;
}
错误信息
encrypted string:�Bj�.�Ntk�F�`�
encrypted key:ThisIsASecretKey
decrypted value:null
May 25,2012 12:54:02 PM bean.Test decrypt
SEVERE: null
javax.crypto.BadPaddingException: Given final block not properly padded
at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
at com.sun.crypto.provider.AESCipher.engineDoFinal(DashoA13*..)
at javax.crypto.Cipher.doFinal(DashoA13*..)
at bean.Test.decrypt(Test.java:55)
at bean.Test.main(Test.java:24)
最后我基于@QuantumMechanic答案使用以下解决方案
public class Test {
public String encryptionKey;
public static void main(String args[]) {
Test t = new Test();
String encrypt = t.encrypt("mypassword");
System.out.println("decrypted value:" + t.decrypt(t.encryptionKey,encrypt));
}
public String encrypt(String value) {
try {
// Get the KeyGenerator
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(256);
// Generate the secret key specs.
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
String key = new Base64().encodeAsString(raw);
this.encryptionKey = key;
System.out.println("------------------Key------------------");
System.out.println(key);
System.out.println("--------------End of Key---------------");
SecretKeySpec skeySpec = new SecretKeySpec(raw,skeySpec);
String encrypt = (new Base64()).encodeAsString(cipher.doFinal(value.getBytes()));
System.out.println("encrypted string:" + encrypt);
return encrypt;
} catch (NoSuchAlgorithmException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE,String encrypted) {
try {
Key k = new SecretKeySpec(Base64.getDecoder().decode(key),"AES");
Cipher c = Cipher.getInstance("AES");
c.init(Cipher.DECRYPT_MODE,k);
byte[] decodedValue = Base64.getDecoder().decode(encrypted);
byte[] decValue = c.doFinal(decodedValue);
String decryptedValue = new String(decValue);
return decryptedValue;
} catch (IllegalBlockSizeException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE,ex);
}
return null;
}
}
以上是大佬教程为你收集整理的Java AES加密和解密全部内容,希望文章能够帮你解决Java AES加密和解密所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。