javax.crypto.BadPaddingException:给定最终块在解密时没有正确填充错误

时间:2013-11-30 07:07:56

标签: java encryption

我正在对数据进行加密和解密,但是会出现错误

protected Cipher aes_Gen_with_Key(byte[] key)
    {
        Cipher cipher=null;
        try
        {
        byte[] key_hash = (key).toString().getBytes("UTF-8");
        key_hash = Arrays.copyOf(key_hash, 32); // use only first 256 bit
        SecretKeySpec secretKeySpec = new SecretKeySpec(key_hash, "AES"); 
        cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);

        } catch (Exception e) {
            System.out.println("Error Occured");
        }
        return cipher;
    }

    protected Cipher aes_Dec_with_Key(byte[] key,byte[] iv)
    {
        Cipher cipher=null;
        try
        {
        byte[] key_hash = (key).toString().getBytes("UTF-8");
        key_hash = Arrays.copyOf(key_hash, 32); // use only first 256 bit
        SecretKeySpec secretKeySpec = new SecretKeySpec(key_hash, "AES");
        cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE,secretKeySpec,new IvParameterSpec(iv));
        }
        catch (Exception e) {
            System.out.println(e);
        }

        return cipher;
    }

使用上述两个函数,我得到了我正在进行加密和解密的密码,但得到javax.crypto.BadPaddingException:给定最终块没有正确填充为错误。解密字节数组的长度为752,解密时的IV为16字节长。任何人都可以建议吗?

以下是一些更相关的代码块。 无效使用java命名约定的道歉

   // Key Class
    import java.io.Serializable;
    @SuppressWarnings("serial")
    public class Key implements Serializable{
        byte[] gsmodp_hash=null;
        byte[] iv_pass=null;
        byte[] Nonce_Enc=null;
        byte[] iv_non=null;
        public Key() {
        }

        public Key(byte[] gsmodp_hash,byte[] iv_pass,byte[] Nonce_Enc,byte[] iv_non) {
            this.gsmodp_hash=gsmodp_hash;
            this.iv_pass=iv_pass;
            this.Nonce_Enc=Nonce_Enc;
            this.iv_non=iv_non;
        }
    }

    // Client side code

            JSONObject auth_step_obj=new JSONObject();
            try {

                BigInteger gsmodp=get_modu_frm_server(receivePacket);
                BigInteger R2=get_R2_frm_server(receivePacket);
                BigInteger N2=get_N2_frm_server(receivePacket);
                N2=crypto.dec_NonceG(N2);
                BigInteger a=crypto.get_RandLong();
                BigInteger gamodp= crypto.dh_GenerationG(a, crypto.g, crypto.p);
                BigInteger key=crypto.dh_GenerationG(a, gsmodp, crypto.p);

                // Got hash of g^abmodp

                byte[] dhkey=crypto.sha256G(key.toString());
                key=null;
                //Mixing passwords

                SecretKey secretkey=(SecretKey) userCredentials.get("password");
                byte[] mixed_hash=crypto.passwordMixerG(R2, secretkey.getEncoded());

                //Working Fine Till now
                // Getting Cipher for encrypting gsmodp using password and nonce
                Cipher cipher_password=crypto.aes_Gen_with_Key(mixed_hash);
                Cipher cipher_key=crypto.aes_Gen_with_Key(dhkey);

                // Generating quantities for JSON Object        
                byte[] gsmodp_hash=cipher_password.doFinal(gamodp.toString().getBytes());
                byte[] gsmodp_hash_iv=cipher_password.getIV();
                byte[] nonce_enc=cipher_key.doFinal(N2.toString().getBytes());
                byte[] nonce_enc_iv=cipher_key.getIV();
                Key authetication_parameters=new Key(gsmodp_hash,gsmodp_hash_iv,nonce_enc,nonce_enc_iv);
                auth_step_obj.put("obj",authetication_parameters);

            } catch (Exception e) {
                // TODO Auto-generated catch block
                System.out.println("Hi:sec_DH_Step");
            } 
            // This sends JSONObject to calling method which generates UDP packet and sends to server 
            return auth_step_obj;
        }

    // Server side code
    // Once packet received on server following happens
    ds.receive(receivePacket);
    SecretKey userKey=cryptoObj.get_from_KeyStoreG(user_name);
    // Adding R2 and userKey byte by byte
    byte[] mixed_hash=cryptoObj.passwordMixerG(R2, userKey.getEncoded());
    JSONObject authentication_nonce=new JSONObject();
    authentication_nonce=cryptoObj.readRecievedPacket(receivePacket);
    Key obj=(Key)authentication_nonce.get("obj");
    Cipher cipher=cryptoObj.aes_Dec_with_Key(mixed_hash,obj.iv_pass);
    // I am getting error on do final
    System.out.println(new String(cipher.doFinal(obj.gsmodp_hash)));

1 个答案:

答案 0 :(得分:3)

您提供的代码工作得很好。错误必须存在于您未与我们共享的代码中(即实际使用Cipher对象的代码)。

我编写了以下代码来测试您的问题代码:

public static void main(String[] args) throws Exception {

  Random random = new Random();
  byte[] key = new byte[32];
  random.nextBytes(key);

  byte[] plaintext = new byte[100];
  random.nextBytes(plaintext);

  Cipher enc = aes_Gen_with_Key(key);

  byte[] ciphertext = enc.doFinal(plaintext);
  byte[] iv = enc.getIV();

  Cipher dec = aes_Dec_with_Key(key, iv);

  byte[] recoveredPlaintext = dec.doFinal(ciphertext);

  System.out.println(Arrays.equals(plaintext, recoveredPlaintext));    
}

注意,我让你的两个方法都是静态的。你应该这样做,因为它们不使用任何实例变量。