Java 爪哇语;给定未正确填充的最后一块“;Tomcat5.5服务器中的异常
我在解码加密文本时遇到问题。Java 爪哇语;给定未正确填充的最后一块“;Tomcat5.5服务器中的异常,java,tomcat,encryption,Java,Tomcat,Encryption,我在解码加密文本时遇到问题。 当收到加密消息时,Java有时会抛出下面的异常 javax.crypto.BadPaddingException: Given final block not properly padded at com.sun.crypto.provider.SunJCE_h.b(DashoA12275) at com.sun.crypto.provider.SunJCE_h.b(DashoA12275) at com.sun.crypto.provide
当收到加密消息时,Java有时会抛出下面的异常
javax.crypto.BadPaddingException: Given final block not properly padded
at com.sun.crypto.provider.SunJCE_h.b(DashoA12275)
at com.sun.crypto.provider.SunJCE_h.b(DashoA12275)
at com.sun.crypto.provider.SunJCE_af.b(DashoA12275)
at com.sun.crypto.provider.PBEWithMD5AndDESCipher.engineDoFinal(DashoA12275)
at javax.crypto.Cipher.doFinal(DashoA12275)
at com.inv.my.encrypt.StringEncrypter.decrypt(StringEncrypter.java:206)
at com.inv.my.encrypt.EncryptDecryptMachine.decrypt(EncryptDecryptMachine.java:56)
at com.inv.my.servlet.transfer.hq.RequestStockQty.doPost(RequestStockQty.java:47)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:592)
at org.apache.catalina.security.SecurityUtil$1.run(SecurityUtil.java:244)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAsPrivileged(Subject.java:517)
at org.apache.catalina.security.SecurityUtil.execute(SecurityUtil.java:276)
at org.apache.catalina.security.SecurityUtil.doAsPrivilege(SecurityUtil.java:162)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:262)
at org.apache.catalina.core.ApplicationFilterChain.access$0(ApplicationFilterChain.java:192)
at org.apache.catalina.core.ApplicationFilterChain$1.run(ApplicationFilterChain.java:171)
at java.security.AccessController.doPrivileged(Native Method)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:167)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:172)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:151)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:874)
at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665)
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)
at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:689)
at java.lang.Thread.run(Thread.java:595)
我的服务器设置是
public class StringEncrypter {
Cipher ecipher;
Cipher dcipher;
public StringEncrypter(SecretKey key, String algorithm) {
try {
ecipher = Cipher.getInstance(algorithm);
dcipher = Cipher.getInstance(algorithm);
ecipher.init(Cipher.ENCRYPT_MODE, key);
dcipher.init(Cipher.DECRYPT_MODE, key);
} catch (NoSuchPaddingException e) {
System.out.println("EXCEPTION: NoSuchPaddingException");
} catch (NoSuchAlgorithmException e) {
System.out.println("EXCEPTION: NoSuchAlgorithmException");
} catch (InvalidKeyException e) {
System.out.println("EXCEPTION: InvalidKeyException");
}
}
public StringEncrypter(String passPhrase) {
setPassPhrase( passPhrase );
}
public void setPassPhrase( String passPhrase ) {
// 8-bytes Salt
byte[] salt = {
(byte)0xA9, (byte)0x9B, (byte)0xC8, (byte)0x32,
(byte)0x56, (byte)0x34, (byte)0xE3, (byte)0x03
};
// Iteration count
int iterationCount = 19;
try {
KeySpec keySpec = new PBEKeySpec(passPhrase.toCharArray(), salt, iterationCount);
SecretKey key = SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(keySpec);
ecipher = Cipher.getInstance(key.getAlgorithm());
dcipher = Cipher.getInstance(key.getAlgorithm());
// Prepare the parameters to the cipthers
AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt, iterationCount);
ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
} catch (InvalidAlgorithmParameterException e) {
System.out.println("EXCEPTION: InvalidAlgorithmParameterException");
} catch (InvalidKeySpecException e) {
System.out.println("EXCEPTION: InvalidKeySpecException");
} catch (NoSuchPaddingException e) {
System.out.println("EXCEPTION: NoSuchPaddingException");
} catch (NoSuchAlgorithmException e) {
System.out.println("EXCEPTION: NoSuchAlgorithmException");
} catch (InvalidKeyException e) {
System.out.println("EXCEPTION: InvalidKeyException");
}
}
public String encrypt(String str) {
try {
// Encode the string into bytes using utf-8
byte[] utf8 = str.getBytes("UTF8");
// Encrypt
byte[] enc = ecipher.doFinal(utf8);
// Encode bytes to base64 to get a string
return new sun.misc.BASE64Encoder().encode(enc);
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public String decrypt(String str) {
try {
// Decode base64 to get bytes
byte[] dec = new sun.misc.BASE64Decoder().decodeBuffer(str);
System.out.println( "[decrypt]BASE64Decoded????? " + dec );
System.out.println( "[decrypt]Algo: " + dcipher.getAlgorithm() );
System.out.println( "[decrypt]Block Size: " + dcipher.getBlockSize() );
System.out.println( "[decrypt]Parameters: " + dcipher.getParameters().getEncoded() );
// Decrypt
byte[] utf8 = dcipher.doFinal(dec);
// Decode using utf-8
return new String(utf8, "UTF8");
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
编辑添加代码: 我使用的代码来自 对它做了一点修改,下面是我的实际代码。我删除了这些评论,使其更简短 谢谢
public class StringEncrypter {
Cipher ecipher;
Cipher dcipher;
public StringEncrypter(SecretKey key, String algorithm) {
try {
ecipher = Cipher.getInstance(algorithm);
dcipher = Cipher.getInstance(algorithm);
ecipher.init(Cipher.ENCRYPT_MODE, key);
dcipher.init(Cipher.DECRYPT_MODE, key);
} catch (NoSuchPaddingException e) {
System.out.println("EXCEPTION: NoSuchPaddingException");
} catch (NoSuchAlgorithmException e) {
System.out.println("EXCEPTION: NoSuchAlgorithmException");
} catch (InvalidKeyException e) {
System.out.println("EXCEPTION: InvalidKeyException");
}
}
public StringEncrypter(String passPhrase) {
setPassPhrase( passPhrase );
}
public void setPassPhrase( String passPhrase ) {
// 8-bytes Salt
byte[] salt = {
(byte)0xA9, (byte)0x9B, (byte)0xC8, (byte)0x32,
(byte)0x56, (byte)0x34, (byte)0xE3, (byte)0x03
};
// Iteration count
int iterationCount = 19;
try {
KeySpec keySpec = new PBEKeySpec(passPhrase.toCharArray(), salt, iterationCount);
SecretKey key = SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(keySpec);
ecipher = Cipher.getInstance(key.getAlgorithm());
dcipher = Cipher.getInstance(key.getAlgorithm());
// Prepare the parameters to the cipthers
AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt, iterationCount);
ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
} catch (InvalidAlgorithmParameterException e) {
System.out.println("EXCEPTION: InvalidAlgorithmParameterException");
} catch (InvalidKeySpecException e) {
System.out.println("EXCEPTION: InvalidKeySpecException");
} catch (NoSuchPaddingException e) {
System.out.println("EXCEPTION: NoSuchPaddingException");
} catch (NoSuchAlgorithmException e) {
System.out.println("EXCEPTION: NoSuchAlgorithmException");
} catch (InvalidKeyException e) {
System.out.println("EXCEPTION: InvalidKeyException");
}
}
public String encrypt(String str) {
try {
// Encode the string into bytes using utf-8
byte[] utf8 = str.getBytes("UTF8");
// Encrypt
byte[] enc = ecipher.doFinal(utf8);
// Encode bytes to base64 to get a string
return new sun.misc.BASE64Encoder().encode(enc);
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public String decrypt(String str) {
try {
// Decode base64 to get bytes
byte[] dec = new sun.misc.BASE64Decoder().decodeBuffer(str);
System.out.println( "[decrypt]BASE64Decoded????? " + dec );
System.out.println( "[decrypt]Algo: " + dcipher.getAlgorithm() );
System.out.println( "[decrypt]Block Size: " + dcipher.getBlockSize() );
System.out.println( "[decrypt]Parameters: " + dcipher.getParameters().getEncoded() );
// Decrypt
byte[] utf8 = dcipher.doFinal(dec);
// Decode using utf-8
return new String(utf8, "UTF8");
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
编辑添加的调试日志
Encrypted: HS/uG4F/TZEN/lzX4xGvEQ==
[decrypt]BASE64Decoded????? [B@18df65f
[decrypt]Algo: PBEWithMD5AndDES
[decrypt]Block Size: 8
[decrypt]Parameters: [B@1139ac8
更好的测井数据
Encrypted: HS/uG4F/TZEN/lzX4xGvEQ==
[decrypt]BASE64Decoded????? [B@11b7a20
[decrypt]BASE64Decoded String??? 1D 2F EE 1B 81 7F 4D 91 0D FE 5C D7 E3 11 AF 11
[decrypt]BASE64Decoded Length: 16
[decrypt]Algo: PBEWithMD5AndDES
[decrypt]Block Size: 8
[decrypt]Parameters: 30 0D 04 08 A9 9B C8 32 56 34 E3 03 02 01 13
[decrypt]After decryption:68 71 53 69 64 5F 37 36 39
Decrypted: hqSid_769
在同步功能之后添加了更多日志记录
Request data: hqSid_3443
[encrypt] String??? 68 71 53 69 64 5F 33 34 34 33
[encrypt] Encrypted??? C7 02 03 2D BD F9 A6 6A 93 C0 40 48 2E 5F 2B E5
[encrypt]Encrypted �-��j��@H._+�
[encrypt]Encrypted Length 16
[encrypt]Algo: PBEWithMD5AndDES
[encrypt]Block Size: 8
[encrypt]Parameters: [B@f5cbda
收到
Encrypted: xwIDLb35pmqTwEBILl8r5Q==
[decrypt]BASE64Decoded????? [B@13cd5ba
[decrypt]BASE64Decoded String??? C7 02 03 2D BD F9 A6 6A 93 C0 40 48 2E 5F 2B E5
[decrypt]BASE64Decoded Length: 16
[decrypt]Algo: PBEWithMD5AndDES
[decrypt]Block Size: 8
[decrypt]dcipher.Parameters().getEncoded(): 30 0D 04 08 A9 9B C8 32 56 34 E3 03 02 01 13
javax.crypto.BadPaddingException: Given final block not properly padded...
这段代码绝对不是线程安全的,这似乎就是问题所在。您需要为每个线程使用不同的密码对象。您能给我们看一些代码吗?你用什么加密?看这里。代码是按要求添加的。我对密码学相当陌生,我仍在试图理解ditkin发布的链接。我仍然想知道为什么重新启动我的tomcat来修复它=/@Jeff运行代码(加密和解密)时得到的调试输出是什么。。。不确定密码,因为我在mysql数据库中存储了密码/salt。。。如果正确检索到密码,我会尝试记录它。FWIW,一个常量salt实际上不是salt。你应该使用一个随机的salt并用散列密码存储它。哇。。。到现在为止,一直都还不错。。一整天也不例外。。。之前发生的事情是,我将类放在一个单例中,这样我就可以再次重用它了。。。。我更改了它,这样每次调用它都会创建上面类的新对象=/看起来我关于线程安全性的评论可能是读取问题:您不能跨线程共享密码实例,否则任何东西都无法正常工作,因为所有线程都将使用相同的密码对象并造成混乱。我将编辑答案以反映这一点。我将进行更多的测试,但这取得了良好的进展。^但有一个问题,我可以在任何地方了解更多关于密码和最佳实践的信息?