关于解决RSA非对称加密时,将密文存入数据库取出后,再对密文解密的时候抛出javax.crypto.BadPaddingException: Data must start with zero

来源:互联网 发布:河南软件服务协会 编辑:程序博客网 时间:2024/05/19 00:55

   RSA非对称加密,由于其对加密的明文长度有限制,所以通常配合对称加密来操作,即把对称加密中的秘钥加密传送来保证用对称加密的安全性。当我用RSA公钥加密AES的 密钥之后,存入mysql之后,然后再取出来进行解密,但是报错javax.crypto.BadPaddingException: Data must start with zero。我改了半天,终于想了一个解决办法,虽然有些麻烦,但是有效果。希望大家多多指教。其实解决思想很简单,就是把加密后的密文放入一个对象中,然后把对象序列化再存入数据库,然后再把对象从数据库取出,再取出其中的密文域的密文。

RSA加密部分:

package com.test;import java.security.*;import java.util.ArrayList;import javax.crypto.*;public class RSA {         private KeyPairGenerator kePaGen=null;                //秘密钥匙生成器;    private KeyPair          keyPair=null;                //钥匙对,公尺 和米尺;    private PublicKey        publicKey=null;              //共匙;    private PrivateKey       privateKey=null;             //密匙;    private int             keySize    =2048;               //密匙长        public RSA(int keysize) {        this.keySize= keysize;        try{        this.kePaGen= KeyPairGenerator.getInstance("RSA"); //        this.kePaGen.initialize(this.keySize);           //        this.keyPair=this.kePaGen.genKeyPair();        this.privateKey=this.keyPair.getPrivate();        this.publicKey=this.keyPair.getPublic();         //this.abcharRsaCipher=Cipher.getInstance("RSA/ECB/PKCS1Padding");        }catch( Exception err){            err.printStackTrace();        }           }    public static String encripyRSA(String platxt,PublicKey publickey)    {        String cipherStr=null;                              //返回的加密后的字符串;              byte[]plainByte=null;                              //获得明文的byte数组;         byte[]cipherByte;                                    //产生秘闻的byte数组;                                  Cipher cipher =null;        try{                  plainByte=platxt.getBytes("ISO-8859-1");         cipher=Cipher.getInstance("RSA/ECB/PKCS1Padding");        cipher.init(Cipher.ENCRYPT_MODE,publickey);         cipherByte=cipher.doFinal(plainByte);                cipherStr=new String(cipherByte,"ISO-8859-1");          }catch(Exception err){            err.printStackTrace();            System.out.println("error in en: "+err.toString());        }        return cipherStr;    }        public static String decripyRSA(String cphtxt,PrivateKey privateKey)    {         byte[] cipherByte =null;                             //获得秘闻的byte数组;                 byte[] plainByte   =null;                             //解密后的明文数组;         String   plainStr    =null;                            //解密后的明文数组;         Cipher   cipher      =null;                            //加密用;        try{            cipherByte       =cphtxt.getBytes("ISO-8859-1");    //统一使用该种编码方式;            cipher =Cipher.getInstance("RSA/ECB/PKCS1Padding");            cipher.init(Cipher.DECRYPT_MODE,privateKey);            plainByte=cipher.doFinal(cipherByte);            plainStr=new String(plainByte,"ISO-8859-1");                 }catch(Exception err)        {            err.printStackTrace();        }        return plainStr;    }        public PublicKey getPublicKey()    {        return this.publicKey;    }    public PrivateKey getPrivateKey()    {        return this.privateKey;    }        public static void main(String []args)    {    RSA arsa=new RSA(2048);    PublicKey publicKey=arsa.getPublicKey();    System.out.println(publicKey);        String en=RSA.encripyRSA("101",publicKey);              PrivateKey privateKey=arsa.getPrivateKey();        System.out.println(privateKey);                           Dao dao=new Daoimpl();        CC cc=new CC(en);//将密文存入一个对象        dao.addObject(cc);//将对象存入数据库        ArrayList<CC> list=dao.queryCC();//从数据库中获取存入的对象        String cString=null;cString =list.get(0).cString;//将对象中的密文取出        System.out.println("cString: "+cString);        String de=RSA.decripyRSA(cString,privateKey);//现在用从数据库取出的密文就可以成功解密,就不会出现这个异常,javax.crypto.BadPaddingException: Data must start with zero        System.out.println(de);        dao.close();      }}

数据库操作部分:

package com.test;import java.math.BigInteger;import java.util.ArrayList;public interface Dao {public abstract int queryRecordsCount();public abstract boolean addObject(CC cc);public abstract ArrayList<CC> queryObject();public abstract void close();}

package com.test;import java.io.BufferedInputStream;import java.io.ByteArrayInputStream;import java.io.InputStream;import java.io.ObjectInputStream;import java.math.BigInteger;import java.sql.Blob;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.util.ArrayList;public class Daoimpl implements Dao {private Connection connection;private ResultSet rs;    PreparedStatement pst ;public Daoimpl(){connection=DBOperations.getConnection();}@Overridepublic boolean addObject(CC cc) {// TODO Auto-generated method stubboolean result=false;int i=0; String sql="insert into test(c) values(?)"; try {pst = connection.prepareStatement(sql);      pst.setObject(1, cc);i = pst.executeUpdate();  } catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}         //执行插入数据操作,返回影响的行数 if (i == 1) {     result = true; } return result;}@Overridepublic ArrayList<CC> queryObject() {// TODO Auto-generated method stub        ArrayList<CC> result=new ArrayList<>();        String sql="select * from test";        try        {            pst = connection.prepareStatement(sql);            rs = pst.executeQuery();            int i=0;            while(rs.next())            {                Blob inBlob=rs.getBlob(2);                             //获取blob对象                                  InputStream is=inBlob.getBinaryStream();                //获取二进制流对象                  BufferedInputStream bis=new BufferedInputStream(is);                                byte[] buff=new byte[(int) inBlob.length()];                  while(-1!=(bis.read(buff, 0, buff.length))){            //一次性全部读到buff中                      ObjectInputStream in=new ObjectInputStream(new ByteArrayInputStream(buff));                      CC p=(CC)in.readObject();                   //读出对象                                            result.add(p);                  }                             }        }        catch (Exception e)        {            e.printStackTrace();        }        return result; }@Overridepublic int queryRecordsCount() {        int result = 0;        String sql="select count(*) from test";        try        {            pst = connection.prepareStatement(sql);            rs = pst.executeQuery();            if (rs.next())            {                result = rs.getInt(1);            }        }        catch (Exception e)        {            e.printStackTrace();        }        return result;}@Overridepublic void close() {// TODO Auto-generated method stubDBOperations.freeResource(connection, pst, rs);}}

序列化的对象:

package com.test;import java.io.Serializable;public class CC implements Serializable {public String cString;public CC(String cString) {super();this.cString = cString;}}


最后是数据库的字段表:


阅读全文
0 0
原创粉丝点击