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 chb.test.crypto.AESUtils.crypt(AESUtils.java:386)
       at chb.test.crypto.AESUtils.AesDecrypt(AESUtils.java:254)
       at chb.test.crypto.AESUtils.main(AESUtils.java:40)

解决方法:

经过检查之后,定位在生成KEY的方法上,如下:

viw plaincopy to clipboardprint?

  1. public static SecretKey getKey (String strKey) {

  2. try {

  3. KeyGenerator _generator = KeyGenerator.getInstance( "AES" );

  4. _generator.init(128, new SecureRandom(strKey.getBytes()));

  5. return _generator.generateKey();

  6. }  catch (Exception e) {

  7. throw new RuntimeException( " 初始化密钥出现异常 " );

  8. }

  9. }

修改到如下方式,问题解决:

view plaincopy to clipboardprint?

  1. public static SecretKey getKey(String strKey) {

  2. try {

  3. KeyGenerator _generator = KeyGenerator.getInstance( "AES" );

  4. SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG" );

  5. secureRandom.setSeed(strKey.getBytes());

  6. _generator.init(128,secureRandom);

  7. return _generator.generateKey();

  8. }  catch (Exception e) {

  9. throw new RuntimeException( " 初始化密钥出现异常 " );

  10. }

  11. }

原因分析

SecureRandom 实现完全隨操作系统本身的內部狀態,除非調用方在調用 getInstance 方法之後又調用了 setSeed 方法;该实现在 windows 上每次生成的 key 都相同,但是在 solaris 或部分 linux 系统上则不同。

一般情况下

package util;

import java.io.UnsupportedEncodingException;

import java.security.InvalidKeyException;

import java.security.NoSuchAlgorithmException;

import java.security.SecureRandom;

import javax.crypto.BadPaddingException;

import javax.crypto.Cipher;

import javax.crypto.IllegalBlockSizeException;

import javax.crypto.KeyGenerator;

import javax.crypto.NoSuchPaddingException;

import javax.crypto.SecretKey;

import javax.crypto.spec.SecretKeySpec;

public class AESUtil {

/**

* 加密

*

* @param content 需要加密的内容

* @param password  加密密码

* @return

*/

public static byte[] encrypt(String content, String password) {

try {

KeyGenerator kgen = KeyGenerator.getInstance("AES");

//kgen.init(128, new SecureRandom(password.getBytes()));

SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG" );

secureRandom.setSeed(password.getBytes());

kgen.init(128,secureRandom);

SecretKey secretKey = kgen.generateKey();

byte[] enCodeFormat = secretKey.getEncoded();

SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");

Cipher cipher = Cipher.getInstance("AES");// 创建密码器

byte[] byteContent = content.getBytes("utf-8");

cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化

byte[] result = cipher.doFinal(byteContent);

return result; // 加密

} catch (NoSuchAlgorithmException e) {

e.printStackTrace();

} catch (NoSuchPaddingException e) {

e.printStackTrace();

} catch (InvalidKeyException e) {

e.printStackTrace();

} catch (UnsupportedEncodingException e) {

e.printStackTrace();

} catch (IllegalBlockSizeException e) {

e.printStackTrace();

} catch (BadPaddingException e) {

e.printStackTrace();

}

return null;

}

/**解密

* @param content  待解密内容

* @param password 解密密钥

* @return

*/

public static byte[] decrypt(byte[] content, String password) {

try {

KeyGenerator kgen = KeyGenerator.getInstance("AES");

//kgen.init(128, new SecureRandom(password.getBytes()));

SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG" );

secureRandom.setSeed(password.getBytes());

kgen.init(128,secureRandom);

SecretKey secretKey = kgen.generateKey();

byte[] enCodeFormat = secretKey.getEncoded();

SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");

Cipher cipher = Cipher.getInstance("AES");// 创建密码器

cipher.init(Cipher.DECRYPT_MODE, key);// 初始化

byte[] result = cipher.doFinal(content);

return result; // 加密

} catch (NoSuchAlgorithmException e) {

e.printStackTrace();

} catch (NoSuchPaddingException e) {

e.printStackTrace();

} catch (InvalidKeyException e) {

e.printStackTrace();

} catch (IllegalBlockSizeException e) {

e.printStackTrace();

} catch (BadPaddingException e) {

e.printStackTrace();

}

return null;

}

/**将二进制转换成16进制

* @param buf

* @return

*/

public static String parseByte2HexStr(byte buf[]) {

StringBuffer sb = new StringBuffer();

for (int i = 0; i < buf.length; i++) {

String hex = Integer.toHexString(buf[i] & 0xFF);

if (hex.length() == 1) {

hex = '0' + hex;

}

sb.append(hex.toUpperCase());

}

return sb.toString();

}

/**将16进制转换为二进制

* @param hexStr

* @return

*/

public static byte[] parseHexStr2Byte(String hexStr) {

if (hexStr.length() < 1)

return null;

byte[] result = new byte[hexStr.length()/2];

for (int i = 0;i< hexStr.length()/2; i++) {

int high = Integer.parseInt(hexStr.substring(i*2, i*2+1), 16);

int low = Integer.parseInt(hexStr.substring(i*2+1, i*2+2), 16);

result[i] = (byte) (high * 16 + low);

}

return result;

}

}

AES加密跨平台出现的问题的更多相关文章

  1. 非对称技术栈实现AES加密解密

    非对称技术栈实现AES加密解密 正如前面的一篇文章所述,https协议的SSL层是实现在传输层之上,应用层之下,也就是说在应用层上看到的请求还是明码的,对于某些场景下要求这些http请求参数是非可读的 ...

  2. 透过 Delphi 使用二进位金钥做 AES 加密.

    从 1994 年开始,笔者就开始接触加密与网路安全的世界,从鲁立忠老师的指导当中获益良多,后来在台湾的元智大学就读研究所的时候,也以此为研究主题. 在当时,电子商务是显学,Visa跟 Master C ...

  3. polarssl rsa & aes 加密与解密

    上周折腾加密与解密,用了openssl, crypto++, polarssl, cyassl, 说起真的让人很沮丧,只有openssl & polarssl两个库的RSA & AES ...

  4. polarssl rsa & aes 加密与解密<转>

    上周折腾加密与解密,用了openssl, crypto++, polarssl, cyassl, 说起真的让人很沮丧,只有openssl & polarssl两个库的RSA & AES ...

  5. 关于CryptoJS中md5加密以及aes加密的随笔

    最近项目中用到了各种加密,其中就包括从没有接触过得aes加密,因此从网上各种查,官方的一种说法: 高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学 ...

  6. AES加密

    package com.edu.hpu; import java.math.BigInteger; import java.security.MessageDigest; import java.se ...

  7. Android数据加密之Aes加密

    前言: 项目中除了登陆,支付等接口采用rsa非对称加密,之外的采用aes对称加密,今天我们来认识一下aes加密. 其他几种加密方式: Android数据加密之Rsa加密 Android数据加密之Aes ...

  8. c#和js互通的AES加密解密

    一.使用场景 在使用前后端分离的框架中常常会进行传输数据相互加密解密以确保数据的安全性,如web Api返回加密数据客户端或web端进行解密,或者客户端或web端进行加密提交数据服务端解密数据等等. ...

  9. AES加密解密通用版Object-C / C# / JAVA

    1.无向量 128位 /// <summary> /// AES加密(无向量) /// </summary> /// <param name="plainByt ...

随机推荐

  1. 了解Unicode编码

    制定Unicode编码标准的组织有两个,一个是国际标准化组织ISO,一个是多语言软件制造商组成的统一码联盟. 通用字符集UCS(Universal Character Set)是由ISO制定的编码方案 ...

  2. [转] How to dispatch a Redux action with a timeout?

    How to dispatch a Redux action with a timeout? Q I have an action that updates notification state of ...

  3. Android开发:最详细的 Toolbar 开发实践总结

    最详细的 Toolbar 开发实践总结 过年前发了一篇介绍 Translucent System Bar 特性的文章 Translucent System Bar 的最佳实践,收到很多开发者的关注和反 ...

  4. JAVA 原始国际化例子

    import java.text.MessageFormat; import java.util.Locale; import java.util.ResourceBundle; public cla ...

  5. css考核点整理(九)-有几种文字替换方式,之间的优缺点

    有几种文字替换方式,之间的优缺点

  6. 调优系列-tomcat调优

    http://www.360doc.com/content/14/1208/13/16070877_431273418.shtml 使用JMeter对Tomcat进行压力测试与Tomcat性能调优 n ...

  7. 数据的动态合并和导出至EXCEL

    最近一段时间都在处理数据的动态合并和导出EXCEL的问题,写个demo记录下,希望和我碰到同样问题的博友可以顺利解决:后面会提供demo下载链接. (VS2012,ASP.NET) 一.主要解决以下问 ...

  8. CSS Clip剪切元素实例

    一.实例1: .fixed { position: fixed; width: 382px; height: 100px; background: red; border: 1px solid blu ...

  9. oracle批量导入数据

    关键代码 OracleDataAdapter da=new OracleDataAdapter(); string sql_select = string.Format("select id ...

  10. 使用require.js时,解决AMD封装jquery1.4.1的问题。

    require.config({ baseUrl: "js/", paths: { "jquery": "jquery-1.4.1.min" ...