我写了个DES类,用于加密解密数据,自己测试通过,因业务需要,要解密.NET传过来的DES加密后的密文,报错:
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.DESCipher.engineDoFinal(DashoA13*..)
at javax.crypto.Cipher.doFinal(DashoA13*..)
at test9.DES.decryptMode(DES.java:102)
at test9.Client.main(Client.java:53)
代码如下:
public class DES{

private static final String Algorithm = "DES"; //定义 加密算法,可用 DES,DESede,Blowfish
private static final byte[] keyBytes = {'A','B','C','D','1','2','3','4'}; //为加密密钥,长度为24字节

public DES(){}

/**
 * DES加密
 * @param byte[] src 为被加密的数据缓冲区(源)
 * @return byte[]
 */
public static byte[] encryptMode(byte[] src) {
try {            
//生成密钥            
SecretKey deskey = new SecretKeySpec(keyBytes,Algorithm);            
//加密  
IvParameterSpec iv = new IvParameterSpec(keyBytes);
Cipher c1 = Cipher.getInstance("DES/CBC/PKCS5Padding");
c1.init(Cipher.ENCRYPT_MODE, deskey,iv);            
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;
}
/**
 * DES加密
 * @param String strSrc 为被加密的数据缓冲区(源)
 * @return String
 */
public static String encryptMode(String strSrc) {
try {       
byte[] src = strSrc.getBytes();
//生成密钥            
SecretKey deskey = new SecretKeySpec(keyBytes,"DES");            
//加密            
Cipher c1 = Cipher.getInstance("DES/CBC/PKCS5Padding");            
c1.init(Cipher.ENCRYPT_MODE, deskey);            
return new String(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;
}
/**
 * DES解密
 * @param byte[] src 为加密后的缓冲区
 * @return byte[]
 */
public static byte[] decryptMode(byte[] src) {
try {
//生成密钥
SecretKey deskey = new SecretKeySpec(keyBytes, Algorithm);
//解密
IvParameterSpec iv = new IvParameterSpec(keyBytes);
Cipher c1 = Cipher.getInstance("DES/CBC/PKCS5Padding");
c1.init(Cipher.DECRYPT_MODE, deskey,iv);
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;
}
/**
 * DES解密
 * @param String strSrc 为加密后的缓冲区
 * @return String
 */
public static String decryptMode(String strSrc) {

try {
byte[] src = strSrc.getBytes("UTF-8");
//生成密钥
SecretKey deskey = new SecretKeySpec(keyBytes, "DES");
//解密
IvParameterSpec iv = new IvParameterSpec(keyBytes);
Cipher c1 = Cipher.getInstance("DES/CBC/PKCS5Padding");
c1.init(Cipher.DECRYPT_MODE, deskey,iv);
return new String(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();
}

解决方案 »

  1.   

    private static final String Algorithm = "DES"; //定义 加密算法,可用 DES,DESede,Blowfish
    private static final byte[] keyBytes = {'A','B','C','D','1','2','3','4'}; //为加密密钥,长度为24字节 .net是用这些东西获得密钥的吗?
      

  2.   

    这是我写的代码啊,.net的代码我不知道,但密钥肯定是对的
      

  3.   


    import java.security.Key;
    import java.security.SecureRandom;import javax.crypto.Cipher;
    import javax.crypto.KeyGenerator;import sun.misc.BASE64Decoder;
    import sun.misc.BASE64Encoder;public class DES {

      Key key;  public DES(String str) {
        setKey(str);//生成密匙
      }  public DES() {
    setKey("12345");
      }  /**
       * 根据参数生成KEY
       */
      public void setKey(String strKey) {
          try {
            KeyGenerator _generator = KeyGenerator.getInstance("DES");
            _generator.init(new SecureRandom(strKey.getBytes()));
            this.key = _generator.generateKey();
            _generator = null;
          } catch (Exception e) {
            throw new RuntimeException(
                "Error initializing SqlMap class. Cause: " + e);
          }
      }  /**
       * 加密String明文输入,String密文输出
       */
      public String getEncString(String strMing) {
          byte[] byteMi = null;
          byte[] byteMing = null;
          String strMi = "";
          BASE64Encoder base64en = new BASE64Encoder();
          try {
            byteMing = strMing.getBytes("UTF8");
            byteMi = this.getEncCode(byteMing);
            strMi = base64en.encode(byteMi);
          } catch (Exception e) {
            throw new RuntimeException(
                "Error initializing SqlMap class. Cause: " + e);
          } finally {
            base64en = null;
            byteMing = null;
            byteMi = null;
          }
          return strMi;
      }  /**
       * 解密 以String密文输入,String明文输出
       * @param strMi
       * @return
       */
      public String getDesString(String strMi) {
          BASE64Decoder base64De = new BASE64Decoder();
          byte[] byteMing = null;
          byte[] byteMi = null;
          String strMing = "";
          try {
            byteMi = base64De.decodeBuffer(strMi);
            byteMing = this.getDesCode(byteMi);
            strMing = new String(byteMing, "UTF8");
          } catch (Exception e) {
            throw new RuntimeException(
                "Error initializing SqlMap class. Cause: " + e);
          } finally {
            base64De = null;
            byteMing = null;
            byteMi = null;
          }
          return strMing;
      }  /**
       * 加密以byte[]明文输入,byte[]密文输出
       * @param byteS
       * @return
       */
      private byte[] getEncCode(byte[] byteS) {
          byte[] byteFina = null;
          Cipher cipher;
          try {
            cipher = Cipher.getInstance("DES");
            cipher.init(Cipher.ENCRYPT_MODE, key);
            byteFina = cipher.doFinal(byteS);
          } catch (Exception e) {
            throw new RuntimeException(
                "Error initializing SqlMap class. Cause: " + e);
          } finally {
            cipher = null;
          }
          return byteFina;
      }  /**
       * 解密以byte[]密文输入,以byte[]明文输出
       * @param byteD
       * @return
       */
      private byte[] getDesCode(byte[] byteD) {
          Cipher cipher;
          byte[] byteFina = null;
          try {
            cipher = Cipher.getInstance("DES");
            cipher.init(Cipher.DECRYPT_MODE, key);
            byteFina = cipher.doFinal(byteD);
          } catch (Exception e) {
            throw new RuntimeException(
                "Error initializing SqlMap class. Cause: " + e);
          } finally {
            cipher = null;
          }
          return byteFina;
      }  public static void main(String args[]) {
          DES des = new DES();
          // 设置密钥
          //des.setKey("12345678");      String str1 = "密文";
          //DES加密
          String str2 = des.getEncString(str1);
          String deStr = des.getDesString(str2);
          System.out.println("密文:" + str2);
          //DES解密
          System.out.println("明文:" + deStr);
      }
    }
      

  4.   

    运行你的代码报错:
    Exception in thread "main" java.lang.RuntimeException: Error initializing SqlMap class. Cause: java.lang.RuntimeException: Error initializing SqlMap class. Cause: java.security.InvalidKeyException: No installed provider supports this key: (null)
    at test9.DES2.getEncString(DES2.java:55)
    at test9.DES2.main(DES2.java:139)
      

  5.   

    看看这里对你有没有帮助,是我写的:
    http://www.cnblogs.com/yidinghe/articles/449212.html
      

  6.   

    我也遇到同样的问题,将加密后的密文存到一个txt文件中,再从文件中将密文取出后无法解密,密文前后都是一样的,显示出来也看不出问题,是不是一些不可见字符在存储过程中被改变了,
    如果不存到文件中则没有问题