javax.crypto.IllegalBlockSizeException:最后一个块解密不全 [英] javax.crypto.IllegalBlockSizeException: last block incomplete in decryption

查看:6172
本文介绍了javax.crypto.IllegalBlockSizeException:最后一个块解密不全的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建加密和解密字符串加密方法做工精细,但问题是在解密方法android应用。
系统显示在日志猫的错误:
  javax.crypto.IllegalBlockSizeException:最后一个块解密不全

谁能帮我解决这个错误?

MainActivity.java

 包com.devleb.encdecapp;进口java.io.UnsupportedEncodingException;
进口java.security.GeneralSecurityException;
进口java.security.NoSuchAlgorithmException;
进口java.security.SecureRandom中;进口javax.crypto.Cipher中;
进口javax.crypto.KeyGenerator;
进口javax.crypto.SecretKey;
进口javax.crypto.SecretKeyFactory;
进口javax.crypto.spec.IvParameterSpec;
进口javax.crypto.spec.PBEKeySpec;
进口javax.crypto.spec.PBEParameterSpec;进口android.app.Activity;
进口android.os.Bundle;
进口android.util.Base64;
进口android.util.Log;
进口android.view.ContextMenu;
进口android.view.ContextMenu.ContextMenuInfo;
进口android.view.Menu;
进口android.view.MenuItem;
进口android.view.View;
进口android.view.View.OnClickListener;
进口android.widget.AdapterView;
进口android.widget.AdapterView.OnItemSelectedListener;
进口android.widget.ArrayAdapter;
进口android.widget.Button;
进口android.widget.EditText;
进口android.widget.Spinner;公共类MainActivity扩展活动实现OnClickListener {
    对于布局//意见
    旋转器的旋转;
    的EditText edit_txt_pass;
    静态的EditText edit_txt_enc_string;
    的EditText edit_txt_raw;
    静态的EditText edit_txt_dec_string;
    按钮btn_encrypt,btn_decrypt,btn_clear;    私有静态SecretKey的SKey来;
    静态字符串密文=;
    静态字符串STReditTxtPass;
    串strPaddingencryption;
    静态INT迭代= 1000;
    私有静态最后的String []项目= {填充密钥派生
            SHA1PRNG密钥派生,PBKDF2密钥派生
            PKCS#12密钥推导};    私有静态最后弦乐TAG = MainActivity.class.getSimpleName();
    私有静态最后的String [] =密码{密码,密码
            密码,算法,QWERTY};    // mesage将与密钥绑定到生成的暗号文字
    私有静态纯文本字符串=这是将要加密的文本;    //将用于OnItemSelection方法列表
    私有静态最终诠释PADDING_ENC_IDX = 0;
    私有静态最终诠释SHA1PRNG_ENC_IDX = 1;
    私有静态最终诠释PBKDF2_ENC_IDX = 2;
    私有静态最终诠释PKCS12_ENC_IDX = 3;    字节[] =盐{(字节)为0x11(字节)0x9B(字节)0xC6(字节)0xFE的,
            (字节)0x33(字节)0x44进行,(字节)将0x55(字节)0x77} ;;    静态字节[] ivBytes = {0,0,0,0,0,0,0,0};    @覆盖
    保护无效的onCreate(捆绑savedInstanceState){
        super.onCreate(savedInstanceState);
        的setContentView(R.layout.activity_main);        的KeyGenerator公斤= NULL;
        尝试{
            公斤= KeyGenerator.getInstance(DES);
        }赶上(抛出:NoSuchAlgorithmException E){
            // TODO自动生成catch块
            e.printStackTrace();
        }
        SKey来= kg.generateKey();        //设置与阵列适配器创建微调和
        // DropDownresourse
        旋=(微调)findViewById(R.id.spiner);
        spin.setOnItemSelectedListener(新OnItemSelectedListener(){            @覆盖
            公共无效onItemSelected(适配器视图<>为arg0,ARG1查看,
                    INT ARG2,长ARG3){
                // TODO自动生成方法存根            }            @覆盖
            公共无效onNothingSelected(适配器视图<>为arg0){
                // TODO自动生成方法存根            }
        });        ArrayAdapter<串GT; AA =新ArrayAdapter<串GT;(这一点,
                android.R.layout.simple_spinner_item,项目);
        aa.setDropDownViewResource(android.R.layout.simple_dropdown_item_1line);
        spin.setAdapter(AA);
        //微调code端        edit_txt_pass =(EditText上)findViewById(R.id.editTxtPass);
        edit_txt_enc_string =(EditText上)findViewById(R.id.editTxtEncString);
        edit_txt_raw =(EditText上)findViewById(R.id.editTxtRawKey);
        edit_txt_dec_string =(EditText上)findViewById(R.id.editTxtDecString);        btn_encrypt =(按钮)findViewById(R.id.btnEncrypt);
        btn_encrypt.setOnClickListener(本);        btn_decrypt =(按钮)findViewById(R.id.btnDecrypt);
        btn_decrypt.setOnClickListener(本);        btn_clear =(按钮)findViewById(R.id.btnClear);
        btn_clear.setOnClickListener(本);        // /登记的EDITTEXT到上下文菜单
        registerForContextMenu(edit_txt_pass);    }    //对于明文的加密使用基64
    公共静态字符串toBase64(字节[]字节){
        返回Base64.en codeToString(字节,Base64.NO_WRAP);
    }    公共静态的byte [] fromBase64(字节[]字节){
        //返回Base64.en codeToString(字节,Base64.NO_WRAP);
        返回Base64.de code(字节,Base64.DEFAULT);
    }    @覆盖
    公共无效onCreateContextMenu(文本菜单菜单视图V,
            ContextMenuInfo menuInfo){
        // TODO自动生成方法存根        INT的groupId = 0;
        menu.add(的groupId,1,1,密码);
        menu.add(的groupId,2,2,密码);
        menu.add(的groupId,3,3,密码);
        menu.add(的groupId,4,4,算法);
        menu.add(的groupId,5,5,QWERTY);        super.onCreateContextMenu(菜单,V,menuInfo);
    }    @覆盖
    公共布尔onContextItemSelected(菜单项项){
        // TODO自动生成方法存根        返回的getText(项目);        //返回super.onContextItemSelected(项目);
    }    私人布尔的getText(菜单项项){
        // TODO自动生成方法存根        INT menuItemId = item.getItemId();        如果(menu​​ItemId == 1){
            edit_txt_pass.setText(密码);
        }
        如果(menu​​ItemId == 2){
            edit_txt_pass.setText(密码);
        }
        如果(menu​​ItemId == 3){
            edit_txt_pass.setText(密码);
        }
        如果(menu​​ItemId == 4){
            edit_txt_pass.setText(算法);
        }
        如果(menu​​ItemId == 5){
            edit_txt_pass.setText(QWERTY);
        }
        。STReditTxtPass = edit_txt_pass.getText()的toString();        Log.w(,STReditTxtPass密码文本的字符串);
        返回false;
    }    @覆盖
    公共布尔onCreateOptionsMenu(菜单菜单){
        //充气菜单;如果是present这增加了项目操作栏。
        。getMenuInflater()膨胀(R.menu.main,菜单);
        返回true;
    }    @覆盖
    公共无效的onClick(视图v){
        // TODO自动生成方法存根        如果(V == btn_encrypt){            encryptPadding(明文,盐);
        }否则如果(V == btn_clear){
            edit_txt_enc_string.setText();
        }否则如果(V == btn_decrypt){
            decryptPadding(密文,盐);
        }
    }    公共静态字符串encryptPadding(明文字符串,字节[]盐){
        尝试{            密密码= Cipher.getInstance(DES / CBC / PKCS5Padding);            cipher.init(Cipher.ENCRYPT_MODE,SKey来);            字节[] =密文cipher.doFinal(PlainText.getBytes(UTF-8));            密文=的String.format(%s%s%S,toBase64(盐)],
                    toBase64(密文));
            edit_txt_enc_string.setText(密文);
            返回密文;
        }赶上(GeneralSecurityException E){
            抛出新的RuntimeException(E);
        }赶上(UnsupportedEncodingException五){
            抛出新的RuntimeException(E);
        }
    }    公共静态字符串decryptPadding(字符串CTEXT,字节[]盐){
        尝试{            密密码= Cipher.getInstance(DES / CBC / PKCS5Padding);            IvParameterSpec ivSpec =新IvParameterSpec(ivBytes);
            cipher.init(Cipher.DECRYPT_MODE,SKey来,ivSpec);            字节[] = plaintxt cipher.doFinal(cyphertext.getBytes(UTF-8));            纯文本=的String.format(%s%s%S,fromBase64(盐)],
                    fromBase64(plaintxt));
            edit_txt_dec_string.setText(明文);
            返回纯文本;
        }赶上(GeneralSecurityException E){
            抛出新的RuntimeException(E);
        }赶上(UnsupportedEncodingException五){
            抛出新的RuntimeException(E);
        }
    }}


解决方案

我觉得你有一些倒退关于generel盐和加密。

您有这个,你做的加密结果的内容:

 密文=的String.format(%s%s%S,toBase64(盐)],toBase64(密文));

然后尝试解密上面生成的字符串。这是不可能的。您必须解密相同的字节数组,你回来(你叫密文)。

请在安全读了,如果这是什么严重。该盐用于产生你不钥匙

嘛。这里有云(但你真的需要在解决方案的其他工作,安全读了):

 公共静态字符串encryptPadding(明文字符串,字节[]盐){
    尝试{        密密码= Cipher.getInstance(DES / CBC / PKCS5Padding);        IvParameterSpec ivSpec =新IvParameterSpec(ivBytes);
        cipher.init(Cipher.ENCRYPT_MODE,SKey来,ivSpec);        字节[] =密文cipher.doFinal(PlainText.getBytes(UTF-8));        密文= Base64.en codeToString(密文,Base64.DEFAULT);
        edit_txt_enc_string.setText(密文);
        返回密文;
    }赶上(GeneralSecurityException E){
        抛出新的RuntimeException(E);
    }赶上(UnsupportedEncodingException五){
        抛出新的RuntimeException(E);
    }
}公共静态字符串decryptPadding(字符串CTEXT,字节[]盐){
    尝试{        密密码= Cipher.getInstance(DES / CBC / PKCS5Padding);        IvParameterSpec ivSpec =新IvParameterSpec(ivBytes);
        cipher.init(Cipher.DECRYPT_MODE,SKey来,ivSpec);        字节[] = plaintxt cipher.doFinal(Base64.de code(密文,Base64.DEFAULT));        纯文本=新的String(plaintxt,UTF-8);
        edit_txt_dec_string.setText(明文);
        返回纯文本;
    }赶上(GeneralSecurityException E){
        抛出新的RuntimeException(E);
    }赶上(UnsupportedEncodingException五){
        抛出新的RuntimeException(E);
    }
}

i am creating android application that encrypt and decrypt a string the encrypt method work fine but the problem is in the decrypt method . the system display an error in the log cat : javax.crypto.IllegalBlockSizeException: last block incomplete in decryption

can anyone help me to fix this error ??

MainActivity.java

package com.devleb.encdecapp;

import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;

import android.app.Activity;
import android.os.Bundle;
import android.util.Base64;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;

public class MainActivity extends Activity implements OnClickListener {
    // views for the layout
    Spinner spin;
    EditText edit_txt_pass;
    static EditText edit_txt_enc_string;
    EditText edit_txt_raw;
    static EditText edit_txt_dec_string;
    Button btn_encrypt, btn_decrypt, btn_clear;

    private static SecretKey SKey;
    static String cyphertext = "";
    static String STReditTxtPass;
    String strPaddingencryption;
    static int iterations = 1000;
    private static final String[] items = { "Padding Key derivation",
            "SHA1PRNG key derivation", "PBKDF2 key derivation",
            "PKCS#12 key derivation" };

    private static final String TAG = MainActivity.class.getSimpleName();
    private static final String[] Passwords = { "password", "cryptography",
            "cipher", "algorithm", "qwerty" };

    // mesage that will be binded with the key to generate the cypher text
    private static String PlainText = "this is the text that will be encrypted";

    // the list that will be used for the OnItemSelection method
    private static final int PADDING_ENC_IDX = 0;
    private static final int SHA1PRNG_ENC_IDX = 1;
    private static final int PBKDF2_ENC_IDX = 2;
    private static final int PKCS12_ENC_IDX = 3;

    byte[] salt = { (byte) 0x11, (byte) 0x9B, (byte) 0xC6, (byte) 0xFE,
            (byte) 0x33, (byte) 0x44, (byte) 0x55, (byte) 0x77 };;

    static byte[] ivBytes = { 0, 0, 0, 0, 0, 0, 0, 0 };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        KeyGenerator kg = null;
        try {
            kg = KeyGenerator.getInstance("DES");
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        SKey = kg.generateKey();

        // creation of the spinner with setting Array adapter and
        // DropDownresourse
        spin = (Spinner) findViewById(R.id.spiner);
        spin.setOnItemSelectedListener(new OnItemSelectedListener() {

            @Override
            public void onItemSelected(AdapterView<?> arg0, View arg1,
                    int arg2, long arg3) {
                // TODO Auto-generated method stub

            }

            @Override
            public void onNothingSelected(AdapterView<?> arg0) {
                // TODO Auto-generated method stub

            }
        });

        ArrayAdapter<String> aa = new ArrayAdapter<String>(this,
                android.R.layout.simple_spinner_item, items);
        aa.setDropDownViewResource(android.R.layout.simple_dropdown_item_1line);
        spin.setAdapter(aa);
        // end of the spinner code

        edit_txt_pass = (EditText) findViewById(R.id.editTxtPass);
        edit_txt_enc_string = (EditText) findViewById(R.id.editTxtEncString);
        edit_txt_raw = (EditText) findViewById(R.id.editTxtRawKey);
        edit_txt_dec_string = (EditText) findViewById(R.id.editTxtDecString);

        btn_encrypt = (Button) findViewById(R.id.btnEncrypt);
        btn_encrypt.setOnClickListener(this);

        btn_decrypt = (Button) findViewById(R.id.btnDecrypt);
        btn_decrypt.setOnClickListener(this);

        btn_clear = (Button) findViewById(R.id.btnClear);
        btn_clear.setOnClickListener(this);

        // / for registering the editText to the Context Menu
        registerForContextMenu(edit_txt_pass);

    }

    // for the ciphering of the plainText using the base 64
    public static String toBase64(byte[] bytes) {
        return Base64.encodeToString(bytes, Base64.NO_WRAP);
    }

    public static byte[] fromBase64(byte[] bytes) {
        // return Base64.encodeToString(bytes, Base64.NO_WRAP);
        return Base64.decode(bytes, Base64.DEFAULT);
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v,
            ContextMenuInfo menuInfo) {
        // TODO Auto-generated method stub

        int groupId = 0;
        menu.add(groupId, 1, 1, "password");
        menu.add(groupId, 2, 2, "cryptography");
        menu.add(groupId, 3, 3, "cipher");
        menu.add(groupId, 4, 4, "algorithm");
        menu.add(groupId, 5, 5, "qwerty");

        super.onCreateContextMenu(menu, v, menuInfo);
    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        // TODO Auto-generated method stub

        return getText(item);

        // return super.onContextItemSelected(item);
    }

    private boolean getText(MenuItem item) {
        // TODO Auto-generated method stub

        int menuItemId = item.getItemId();

        if (menuItemId == 1) {
            edit_txt_pass.setText("password");
        }
        if (menuItemId == 2) {
            edit_txt_pass.setText("cryptography");
        }
        if (menuItemId == 3) {
            edit_txt_pass.setText("cipher");
        }
        if (menuItemId == 4) {
            edit_txt_pass.setText("algorithm");
        }
        if (menuItemId == 5) {
            edit_txt_pass.setText("qwerty");
        }
        STReditTxtPass = edit_txt_pass.getText().toString();

        Log.w("the String of the Password text", STReditTxtPass);
        return false;
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub

        if (v == btn_encrypt) {

            encryptPadding(PlainText, salt);
        } else if (v == btn_clear) {
            edit_txt_enc_string.setText("");
        } else if (v == btn_decrypt) {
            decryptPadding(cyphertext, salt);
        }
    }

    public static String encryptPadding(String plaintext, byte[] salt) {
        try {

            Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");

            cipher.init(Cipher.ENCRYPT_MODE, SKey);

            byte[] cipherText = cipher.doFinal(PlainText.getBytes("UTF-8"));

            cyphertext = String.format("%s%s%s", toBase64(salt), "]",
                    toBase64(cipherText));
            edit_txt_enc_string.setText(cyphertext);
            return cyphertext;
        } catch (GeneralSecurityException e) {
            throw new RuntimeException(e);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }

    public static String decryptPadding(String ctext, byte[] salt) {
        try {

            Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");

            IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);
            cipher.init(Cipher.DECRYPT_MODE, SKey, ivSpec);

            byte[] plaintxt = cipher.doFinal(cyphertext.getBytes("UTF-8"));

            PlainText = String.format("%s%s%s", fromBase64(salt), "]",
                    fromBase64(plaintxt));
            edit_txt_dec_string.setText(PlainText);
            return PlainText;
        } catch (GeneralSecurityException e) {
            throw new RuntimeException(e);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }

}

解决方案

I think you have something backwards regarding salt and encryption in generel.

You have this where you do something with the result of the encryption:

cyphertext = String.format("%s%s%s", toBase64(salt), "]", toBase64(cipherText));

Then you try to decrypt the generated string above. That is not possible. You must decrypt the same byte array you get back (you call it cipherText).

Please read up on security if this is anything serious. The salt is used to generate the KEY which you dont.

Well. Here goes (but you really need to work on the rest of the solution and read up on security):

public static String encryptPadding(String plaintext, byte[] salt) {
    try {

        Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");

        IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);
        cipher.init(Cipher.ENCRYPT_MODE, SKey, ivSpec);

        byte[] cipherText = cipher.doFinal(PlainText.getBytes("UTF-8"));

        cyphertext = Base64.encodeToString(cipherText, Base64.DEFAULT);
        edit_txt_enc_string.setText(cyphertext);
        return cyphertext;
    } catch (GeneralSecurityException e) {
        throw new RuntimeException(e);
    } catch (UnsupportedEncodingException e) {
        throw new RuntimeException(e);
    }
}

public static String decryptPadding(String ctext, byte[] salt) {
    try {

        Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");

        IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);
        cipher.init(Cipher.DECRYPT_MODE, SKey, ivSpec);

        byte[] plaintxt = cipher.doFinal(Base64.decode(cyphertext, Base64.DEFAULT));

        PlainText = new String(plaintxt, "UTF-8");
        edit_txt_dec_string.setText(PlainText);
        return PlainText;
    } catch (GeneralSecurityException e) {
        throw new RuntimeException(e);
    } catch (UnsupportedEncodingException e) {
        throw new RuntimeException(e);
    }
}

这篇关于javax.crypto.IllegalBlockSizeException:最后一个块解密不全的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆