import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
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.SecretKeyFactory; import javax.crypto.spec.DESKeySpec;
public class DESEncryptTest {
private static final String DES_ALGORITHM = \"DES\";
Cipher cipher = null; try { } try {
cipher = Cipher.getInstance(DES_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, generateKey(secretKey));
e.printStackTrace(); e.printStackTrace();
/**
* DES加密 * @param plainData * @param secretKey * @return
* @throws Exception */
public String encryption(String plainData, String secretKey) throws Exception{
} catch (NoSuchAlgorithmException e) { } catch (NoSuchPaddingException e) { }catch(InvalidKeyException e){
} /**
}
// 为了防止解密时报javax.crypto.IllegalBlockSizeException: Input length must be multiple of // 不能把加密后的字节数组直接转换成字符串 byte[] buf = cipher.doFinal(plainData.getBytes());
return Base64Utils.encode(buf);
e.printStackTrace();
throw new Exception(\"IllegalBlockSizeException\e.printStackTrace();
throw new Exception(\"BadPaddingException\
8 when decrypting with padded cipher异常,
} catch (IllegalBlockSizeException e) {
} catch (BadPaddingException e) {
* DES解密 * @param secretData * @param secretKey * @return
* @throws Exception */
public String decryption(String secretData, String secretKey) throws Exception{
Cipher cipher = null; try { } try {
cipher = Cipher.getInstance(DES_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, generateKey(secretKey));
e.printStackTrace();
throw new Exception(\"NoSuchAlgorithmException\e.printStackTrace();
throw new Exception(\"NoSuchPaddingException\e.printStackTrace();
throw new Exception(\"InvalidKeyException\
} catch (NoSuchAlgorithmException e) {
} catch (NoSuchPaddingException e) {
}catch(InvalidKeyException e){
} /**
}
byte[] buf = cipher.doFinal(Base64Utils.decode(secretData.toCharArray()));
return new String(buf);
e.printStackTrace();
throw new Exception(\"IllegalBlockSizeException\e.printStackTrace();
throw new Exception(\"BadPaddingException\
} catch (IllegalBlockSizeException e) {
} catch (BadPaddingException e) {
* 获得秘密密钥 *
* @param secretKey * @return
* @throws NoSuchAlgorithmException */
private SecretKey generateKey(String secretKey) throws NoSuchAlgorithmException{ }
public static void main(String[] a) throws Exception{
String input = \"cy11Xlbrmzyh:604:301:1353064296\"; String key = \"37d5aed075525d4fa0fe635231cba447\";
DESEncryptTest des = new DESEncryptTest();
SecureRandom secureRandom = new SecureRandom(secretKey.getBytes());
// 为我们选择的DES算法生成一个KeyGenerator对象 KeyGenerator kg = null; try { }
kg.init(secureRandom); //kg.init(56, secureRandom);
// 生成密钥
return kg.generateKey();
kg = KeyGenerator.getInstance(DES_ALGORITHM); } catch (NoSuchAlgorithmException e) {
}
String result = des.encryption(input, key); System.out.println(result);
System.out.println(des.decryption(result, key));
static class Base64Utils {
static private char[] alphabet =
static private byte[] codes = new byte[256]; static { } /**
* 将原始数据编码为base64编码 */
static public String encode(byte[] data) {
char[] out = new char[((data.length + 2) / 3) * 4];
for (int i = 0, index = 0; i < data.length; i += 3, index += 4) {
boolean quad = false; boolean trip = false;
int val = (0xFF & (int) data[i]); val <<= 8;
if ((i + 1) < data.length) { } val <<= 8;
if ((i + 2) < data.length) { }
val |= (0xFF & (int) data[i + 2]); quad = true;
val |= (0xFF & (int) data[i + 1]); trip = true;
for (int i = 0; i < 256; i++)
codes[i] = -1;
codes[i] = (byte) (i - 'A'); codes[i] = (byte) (26 + i - 'a'); codes[i] = (byte) (52 + i - '0'); for (int i = 'A'; i <= 'Z'; i++) for (int i = 'a'; i <= 'z'; i++) for (int i = '0'; i <= '9'; i++) codes['+'] = 62; codes['/'] = 63;
\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\".toCharArray();
}
}
} /**
}
out[index + 3] = alphabet[(quad ? (val & 0x3F) : 64)]; val >>= 6;
out[index + 2] = alphabet[(trip ? (val & 0x3F) : 64)]; val >>= 6;
out[index + 1] = alphabet[val & 0x3F]; val >>= 6;
out[index + 0] = alphabet[val & 0x3F];
return new String(out);
* 将base64编码的数据解码成原始数据 */
static public byte[] decode(char[] data) { }
int len = ((data.length + 3) / 4) * 3;
if (data.length > 0 && data[data.length - 1] == '=')
--len; --len;
if (data.length > 1 && data[data.length - 2] == '=') byte[] out = new byte[len]; int shift = 0; int accum = 0; int index = 0;
for (int ix = 0; ix < data.length; ix++) { }
if (index != out.length)
throw new Error(\"miscalculated data length!\"); return out;
int value = codes[data[ix] & 0xFF]; if (value >= 0) { }
accum <<= 6; shift += 6; accum |= value; if (shift >= 8) { }
shift -= 8;
out[index++] = (byte) ((accum >> shift) & 0xff);
KKKKkkkkKKKKKKKKKKKKKKK
/*在java中调用sun公司提供的3DES加密解密算法时,需要使用到$JAVA_HOME/jre/lib/目录下如下的4个jar包:
jce.jarsecurity/US_export_policy.jarsecurity/local_policy.jarext/sunjce_provider.jar Java运行时会自动加载这些包,因此对于带main函数的应用程序不需要设置到CLASSPATH环境变量中。对于WEB应用,不需要把这些包加到WEB-INF/lib目录下。
以下是java中调用sun公司提供的3DES加密解密算法的样本代码: */
package com.aaa.aaa; import java.security.*; import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec; public class ThreeDES {
private static final String Algorithm = \"DESede\"; // 定义 加密算法,可用 // DES,DESede,Blowfish
private static final byte[] keyBase = { 0x11, 0x22, 0x4F, 0x58, (byte) 0x88, 0x10, 0x40, 0x38, 0x28, 0x25, 0x79, 0x51, (byte) 0xCB, (byte) 0xDD, 0x55, 0x66, 0x77, 0x29, 0x74, (byte) 0x98, 0x30, 0x40, 0x36, (byte) 0xE2 }; // 24个byte的密钥
// keybyte为加密密钥,长度为24字节 // src为被加密的数据缓冲区(源) /**
* 加密 */
public static byte[] encryptMode(byte[] src) { try {// 生成密钥
SecretKey deskey = new SecretKeySpec(keyBase, Algorithm); // 加密
Cipher c1 = Cipher.getInstance(Algorithm); c1.init(Cipher.ENCRYPT_MODE, deskey); return c1.doFinal(src);
} catch (java.security.NoSuchAlgorithmException e1) { e1.printStackTrace();
} catch (javax.crypto.NoSuchPaddingException e2) { e2.printStackTrace();
} catch (java.lang.Exception e3) { e3.printStackTrace(); }
return null; }
// keybyte为加密密钥,长度为24字节 // src为加密后的缓冲区
public static byte[] decryptMode(byte[] src) { try { // 生成密钥
SecretKey deskey = new SecretKeySpec(keyBase, Algorithm); // 解密
Cipher c1 = Cipher.getInstance(Algorithm); c1.init(Cipher.DECRYPT_MODE, deskey);
return c1.doFinal(src);
} catch (java.security.NoSuchAlgorithmException e1) { e1.printStackTrace();
} catch (javax.crypto.NoSuchPaddingException e2) { e2.printStackTrace();
} catch (java.lang.Exception e3) { e3.printStackTrace(); }
return null; }
// 转换成十六进制字符串
public static String byte2hex(byte[] b) { String hs = \"\"; String stmp = \"\";
for (int n = 0; n < b.length; n++) {
stmp = (java.lang.Integer.toHexString(b[n] & 0XFF)); if (stmp.length() == 1) hs = hs + \"0\" + stmp; else
hs = hs + stmp; if (n < b.length - 1) hs = hs + \":\"; }
return hs.toUpperCase(); }
public static void main(String[] args) {
// 添加新安全算法,如果用JCE就要把它添加进去 Security.addProvider(new com.sun.crypto.provider.SunJCE()); final byte[] keyBytes = { 0x11, 0x22, 0x4F, 0x58, (byte) 0x88, 0x10, 0x40, 0x38, 0x28, 0x25, 0x79, 0x51, (byte) 0xCB, (byte) 0xDD, 0x55, 0x66, 0x77, 0x29, 0x74, (byte) 0x98, 0x30, 0x40, 0x36, (byte) 0xE2 }; // 24字节的密钥
String szSrc = \"This is a 3DES test. 测试\"; System.out.println(\"加密前的字符串:\" + szSrc); byte[] encoded = encryptMode(szSrc.getBytes());
System.out.println(\"加密后的字符串:\" + new String(encoded)); byte[] srcBytes = decryptMode(encoded);
System.out.println(\"解密后的字符串:\" + (new String(srcBytes))); } }
ddddddddddddddddddddd
package com.snailteam.adserver.until; import java.io.UnsupportedEncodingException; import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
/**
* @author :xiaofancn
* @version :2011-11-11 上午11:02:22 * */
public class Tool3DES {
private static final String Algorithm = \"DESede\"; // 定义 加密算法,可用 private static final int Keysize = 168;
/**
* 将byte[]转化成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进制字符串转化成byte[] * @param buf * @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;
}
/**
* 加密
* message->密文byte[]->16进制密文字符串 * @param password * @param message * @return */
public static String encrypt(String password, String message) { } /**
try {
KeyGenerator kgen = KeyGenerator.getInstance(Algorithm); kgen.init(Keysize, new SecureRandom(password.getBytes())); SecretKey secretKey = kgen.generateKey();
byte[] enCodeFormat = secretKey.getEncoded();
SecretKeySpec key = new SecretKeySpec(enCodeFormat, Algorithm); Cipher cipher = Cipher.getInstance(Algorithm);// 创建密码器 byte[] byteContent = message.getBytes(\"utf-8\"); cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化 byte[] result = cipher.doFinal(byteContent); return parseByte2HexStr(result);
} catch (NoSuchAlgorithmException e) { e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (InvalidKeyException e) { e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
e.printStackTrace();
} catch (BadPaddingException e) {
}
return null;
* 解密
* 16进制密文字符串->byte[]->解密 * @param password * @param message * @return
*/
public static String decrypt(String password, String message) { }
public static void main(String[] args) {
String content = \"你好\";
String password = \"123456789\";
System.out.println(\"加密前:\"+content); String temp = encrypt(password, content); System.out.println(\"加密后:\"+temp); KeyGenerator kgen; try {
kgen = KeyGenerator.getInstance(Algorithm);
kgen.init(Keysize, new SecureRandom(password.getBytes())); SecretKey secretKey = kgen.generateKey();
byte[] enCodeFormat = secretKey.getEncoded();
SecretKeySpec key = new SecretKeySpec(enCodeFormat, Algorithm); Cipher cipher = Cipher.getInstance(Algorithm);// 创建密码器 byte[] byteContent = parseHexStr2Byte(message); cipher.init(Cipher.DECRYPT_MODE, key);// 初始化 byte[] result = cipher.doFinal(byteContent); return new String(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;
}
}
temp = decrypt(password, temp); System.out.println(\"解密后:\"+temp);
SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS
解决Linux操作系统下AES解密失败的问题
现象描述:
windows上加解密正常,linux上加密正常,解密时发生如下异常:
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的方法上,如下:
public static SecretKey getKey (String strKey) { try {
KeyGenerator
_generator=KeyGenerator.getInstance(\"AES\"); _generator.init(128, new
SecureRandom(strKey.getBytes()));
return _generator.generateKey(); } catch (Exception e) {
throw new RuntimeException(\"初始化密钥出现异常\"); } }
修改到如下方式,问题解决:
public static SecretKey getKey(String strKey) { try {
KeyGenerator
_generator=KeyGenerator.getInstance(\"AES\"); SecureRandom secureRandom=
SecureRandom.getInstance(\"SHA1PRNG\"); secureRandom.setSeed(strKey.getBytes()); _generator.init(128,secureRandom); return _generator.generateKey(); } catch (Exception e) {
throw new RuntimeException(\"初始化密钥出现异常\"); } }
原因分析:
SecureRandom 实现完全随操作系统本身的內部状态,除非调用方在调用 getInstance 方法之后又调用了 setSeed 方法;该实现在 windows 上每次生成的 key 都相同,但是在 solaris 或部分 linux 系统上则不同。
0 0
今天我也遇到了这个问题,我这边的情况是程序在windows下可以正常运行,在linux则会报这个错误,通过从网上查找发现原因分析
SecureRandom 实现完全隨操作系统本身的內部狀態,除非調用方在調用 getInstance 方法之後又調用了 setSeed 方法;该实现在 windows 上每次生成的 key 都相同,但是在 solaris 或部分 linux 系统上则不同。
在生产秘钥的地方加入以下处理,问题解决。 代码如下:
//防止linux下 随机生成key SecureRandom secureRandom = SecureRandom.getInstance(\"SHA1PRNG\" );
secureRandom.setSeed(keycontent.getBytes()); // 根据密钥初始化密钥生成器
kgen.init(keyNum, secureRandom);
因篇幅问题不能全部显示,请点此查看更多更全内容