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();
}
@Override
public boolean addObject(CC cc) {
// TODO Auto-generated method stub
boolean 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 block
e.printStackTrace();
}
//执行插入数据操作,返回影响的行数
if (i == 1) {
result = true;
}
return result;
}
@Override
public 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;
}
@Override
public 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;
}
@Override
public void close() {
// TODO Auto-generated method stub
DBOperations.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;
}
}
最后是数据库的字段表:

1万+

被折叠的 条评论
为什么被折叠?



