2

I'm having problem with decoding an encrypted text.
When the encrypted message is received, Java would sometimes throw an exception below.

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)

My server setup is...

  1. Ubuntu 8.04 LTS
  2. Java 5
  3. Tomcat5.5

Weirdly enough the problem is intermittent. After restarting the server, it would go away but would come back later again which I would restart my tomcat again just to temporarily fix it.

Thanks!


Edit-Add Code:

The code I use is from...

http://www.idevelopment.info/data/Programming/java/security/java_cryptography_extension/StringEncrypter.java

and modified it a bit, below is my actual code. I removed the comments to make it shorter.

Thanks!

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;
}

}


Edit-Added Debugging Log

Encrypted: HS/uG4F/TZEN/lzX4xGvEQ==
[decrypt]BASE64Decoded????? [B@18df65f
[decrypt]Algo: PBEWithMD5AndDES
[decrypt]Block Size: 8
[decrypt]Parameters: [B@1139ac8

Better Logging Data

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

Added more logging after synchronizing function

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

received

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...
4

1 回答 1

2

This code is definitely not threadsafe, and it appears to be the problem. You will need to use a different Cipher object for each thread.

于 2012-06-04T14:03:48.230 回答