程序问答   发布时间:2022-06-01  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了Java AES加密和解密大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决Java AES加密和解密?

开发过程中遇到Java AES加密和解密的问题如何解决?下面主要结合日常开发的经验,给出你关于Java AES加密和解密的解决方法建议,希望对你解决Java AES加密和解密有所启发或帮助;

如果对于块密码,您将不使用Cipher包含填充方案的转换,则需要使明文中的字节数为该密码的块大小的整数倍。

因此,要么将纯文本填充到16字节的倍数(即AES块大小),要么在创建Cipher对象时指定填充方案。例如,您可以使用:

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5padding");

除非您有充分的理由不这样做,否则请使用JCE实现中已包含的填充方案。他们考虑了许多微妙和极端的情况,否则您将不得不自己意识到和应对这些情况。

好的,您的第二个问题是您String用来保存密文。

一般来说,

String s = new String(someBytes);
byte[] retrIEvedBytes = s.getBytes();

会 有someBytesretrIEvedBytes是相同的。

如果您希望/必须将密文保存在中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,请注明来意。
标签: