我用RSA对文本文件进行加密,但当我的文本文件大小超过1kb时加密、解密就会出错。密钥初始用的1024。希望前辈能指导下。最好能写出关键的源代码(比如,数据的缓冲区设为多大)。
解决方案 »
- weblogic启动web工程包java.lang.NoSuchMethodError
- 请教有关log4j的打印
- jsp页面动态新闻更新
- weblogic server10 JNDI 创建的DataSource对象,有时能连上,有时在取DataSource对象是抛异常
- jsp bean的问题。
- 如何查找sun appserver8上的jms资源
- 上传代码后,出现发送邮件bug:Sealing violation loading ……
- eclipse 中在那里能添加参数? -conf c:\resin\resin.conf
- 做一个调查,看看大家现在都在做什么。
- 求java的正则表达式
- Struts2.1+spring2.5+hibernate3.2 项目出现的问题 怀疑是不是要用JDK1.6版本的
- Myeclipse6.5+jboss-4.2.2.GA构建一个简单的EJB项目
以下是我写的源代码,我不明白为什么要加密的文件一长,就会出错。我测试过,此文本文件的长度在二行以内就不会出错》package rsa;import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.logging.Level;
import java.util.logging.Logger;/**
*
* @author Administrator
*/
public class GenKey {
public static void main(String[] args){//生成密钥
try {
//创建密钥对生成器
KeyPairGenerator KPG = KeyPairGenerator.getInstance("RSA");
//初始化密钥生成器
KPG.initialize(1024);
//生成密钥对
KeyPair KP=KPG.genKeyPair();
//获取公钥和密钥
PublicKey pbKey=KP.getPublic();
PrivateKey prKey=KP.getPrivate();
//保存公钥到文件
FileOutputStream out=new FileOutputStream("RSAPublic.dat");
ObjectOutputStream fileOut=new ObjectOutputStream(out);
fileOut.writeObject(pbKey);
//保存密钥到文件
FileOutputStream outPrivate=new FileOutputStream("RSAPrivate.dat");
ObjectOutputStream privateOut=new ObjectOutputStream(outPrivate);
privateOut.writeObject(prKey);
} catch (Exception ex) {
Logger.getLogger(GenKey.class.getName()).log(Level.SEVERE, null, ex);
} }}
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/package rsatest;import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.OutputStreamWriter;
import java.math.BigInteger;
import java.security.interfaces.RSAPublicKey;
import java.util.logging.Level;
import java.util.logging.Logger;/**
*
* @author Administrator
*/
public class RSAEncrypt {
public static void main(String[] args){
//读取公钥
FileInputStream publicIn=null;
ObjectInputStream objectPublic=null;
try {
// String codeString = "how are you?\n你是?"; //要加密的字符串
publicIn = new //读取公钥
FileInputStream("RSAPublic.dat");
objectPublic=new ObjectInputStream(publicIn);
RSAPublicKey publicKey=(RSAPublicKey)objectPublic.readObject(); //得到公钥的两个重要参数e,n
BigInteger e=publicKey.getPublicExponent();
BigInteger n=publicKey.getModulus();
System.out.println("加密的密钥为:"+e);
System.out.println("加密的模为:"+n);
//读取明文 FileInputStream in=new FileInputStream("test.txt");
// System.out.println(in.available());
int size=in.available();
byte[] encode=new byte[size];
in.read(encode);
String codeString=new String(encode);
System.out.println(codeString);
// codeString = "vi超强挂机类网赚";
//将明文转为大整数
byte[] codeStringByte=codeString.getBytes();
BigInteger m=new BigInteger(codeStringByte);
//加密处理
BigInteger codeStringBigInt=m.modPow(e, n);
String cString=codeStringBigInt.toString();
//保存密文
BufferedWriter out=new BufferedWriter(new OutputStreamWriter
(new FileOutputStream("RSAmi.dat")));
out.write(cString, 0, cString.length());
out.close();
} catch (Exception ex) {
Logger.getLogger(RSAEncrypt.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
publicIn.close();
objectPublic.close();
} catch (IOException ex) {
Logger.getLogger(RSAEncrypt.class.getName()).log(Level.SEVERE, null, ex);
}
}
}}/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/package rsatest;import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.OutputStreamWriter;
import java.math.BigInteger;
import java.security.interfaces.RSAPrivateKey;
import java.util.logging.Level;
import java.util.logging.Logger;/**
*
* @author Administrator
*/
public class RSADecrypt {
public static void main(String[] args){
try {
//读取密文
BufferedReader in = new BufferedReader(new InputStreamReader
(new FileInputStream("RSAmi.dat")));
String ctext=null;
if((ctext=in.readLine())!=null){
//将密文转为大整数
BigInteger bigCtext=new BigInteger(ctext);
//取得密钥
ObjectInputStream objectStream=new ObjectInputStream(new
FileInputStream("RSAPrivate.dat"
));
RSAPrivateKey privateKey=(RSAPrivateKey)objectStream.readObject();
//取得密钥的e,n
BigInteger e=privateKey.getPrivateExponent();
BigInteger n=privateKey.getModulus();
//解密
BigInteger decodeBigInt=bigCtext.modPow(e, n);
byte decodeStringByte[]=decodeBigInt.toByteArray();
String decodeString=new String(decodeStringByte);//此处的编码要和加密时的编码一样,否则会出错
System.out.println("解密后的明文为:"+decodeString);
BufferedWriter out=new BufferedWriter(new OutputStreamWriter
(new FileOutputStream("RSAming.txt")));
out.write(decodeString, 0, decodeString.length());
out.close();
}
} catch (Exception ex) {
Logger.getLogger(RSADecrypt.class.getName()).log(Level.SEVERE, null, ex);
}
}}
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/package rsa;import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.logging.Level;
import java.util.logging.Logger;/**
*
* @author Administrator
*/
public class GenKey {
public static void main(String[] args){//创建密钥
try {
//创建密钥对生成器
KeyPairGenerator KPG = KeyPairGenerator.getInstance("RSA");
//初始化密钥生成器
KPG.initialize(1024);
//生成密钥对
KeyPair KP=KPG.genKeyPair();
//获取公钥和密钥
PublicKey pbKey=KP.getPublic();
PrivateKey prKey=KP.getPrivate();
//保存公钥到文件
FileOutputStream out=new FileOutputStream("RSAPublic.dat");
ObjectOutputStream fileOut=new ObjectOutputStream(out);
fileOut.writeObject(pbKey);
//保存密钥到文件
FileOutputStream outPrivate=new FileOutputStream("RSAPrivate.dat");
ObjectOutputStream privateOut=new ObjectOutputStream(outPrivate);
privateOut.writeObject(prKey);
} catch (Exception ex) {
Logger.getLogger(GenKey.class.getName()).log(Level.SEVERE, null, ex);
} }}
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package rsatest;import cipherinputstream.EncryptAndDecrypt;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.security.Key;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.crypto.Cipher;
import org.bouncycastle.jce.provider.BouncyCastleProvider;/**
*
* @author Administrator
*/
public class RRSSA { public static void main(String[] args) {
//要用作加密或解密的文件名
String dataFileName = args[0];
//是区分是加密还是解密,加密为encrypt,解密为decrypt
String opMode = args[1];
String keyFileName = null;
//密钥存放的文件名
if (opMode.equalsIgnoreCase("encrypt")) {
keyFileName = "RSAPublic.dat";
} else {
keyFileName = "RSAPrivate.dat";
} try {
//生成密钥
FileInputStream keyFIS = new FileInputStream(keyFileName);
ObjectInputStream OIS = new ObjectInputStream(keyFIS);
Key key = (Key) OIS.readObject(); //创建并初始化密码器
Cipher cp = Cipher.getInstance("RSA", new BouncyCastleProvider());//此处不能少
//BouncyCastLeProvider类在bcprov-ext-jdk16-141.jar中
if (opMode.equalsIgnoreCase("encrypt")) { cp.init(Cipher.ENCRYPT_MODE, key);
} else if (opMode.equalsIgnoreCase("decrypt")) {
cp.init(Cipher.DECRYPT_MODE, key);
} else {
return;
} FileInputStream dataFIS = new FileInputStream(dataFileName);
//取得要加密的数据
int size = dataFIS.available();
byte[] encryptByte = new byte[size];
dataFIS.read(encryptByte);
//如果是加密操作
if (opMode.equalsIgnoreCase("encrypt")) {
//建立文件输出流
FileOutputStream FOS = new FileOutputStream("mi.txt");
//RSA算法必须采用分块加密
//取得RSA加密的块的大小
int blockSize = cp.getBlockSize();
//根据给定的输入长度 inputLen(以字节为单位),返回保存下一个 update 或 doFinal 操作结果所需的输出缓冲区长度(以字节为单位)。
int outputBlockSize = cp.getOutputSize(encryptByte.length); //确定要加密的次数(加密块的个数)
int leavedSize = encryptByte.length % blockSize;
int blocksNum = leavedSize == 0 ? encryptByte.length / blockSize
: encryptByte.length / blockSize + 1;
byte[] cipherData = new byte[blocksNum * outputBlockSize];
//对每块数据分别加密
for (int i = 0; i < blocksNum; i++) { if ((encryptByte.length - i * blockSize) > blockSize) {
cp.doFinal(encryptByte, i * blockSize, blockSize, cipherData, i * outputBlockSize);
} else {
cp.doFinal(encryptByte, i * blockSize, encryptByte.length - i * blockSize, cipherData, i * outputBlockSize);
} FOS.write(cipherData);
}
FOS.close(); } else {//如果是解密操作 FileOutputStream FOS = new FileOutputStream("jiemi.txt");
int blockSize = cp.getBlockSize();
int j = 0; //分别对各块数据进行解密
while ((encryptByte.length - j * blockSize) > 0) {
FOS.write(cp.doFinal(encryptByte, j * blockSize, blockSize));
j++;
} FOS.close(); }
} catch (Exception ex) {
Logger.getLogger(EncryptAndDecrypt.class.getName()).log(Level.SEVERE, null, ex);
}
}
}