今天看了CSDN上一篇RSA算法的文章。发现当文本中有多行文字时,解密会无法体现。我初步认为是public void dataEncryption(String source,String destination)这个函数中
long filelength = rafr.length()这个地方有问题,因为回车符号长度为2,所以在加密是无法正确加密。大家讨论看看是否可以解决这个问题呢?
代码如下
import java.io.*;
import java.util.Random;
/** *//**
*Rsa非对称加密的实现
*@author Shaojun Huang
*@version 1.0
*/
public class RSA1
{
private int keyn; //公私钥相同部分
private int publickeye; //公钥
private int privatekeyd; //私钥
/** *//**
*Rsa构造器,初始化对象
*/
public RSA1()
{
int randomprimep = 0; //随机产生素数
int randomprimeq = 0; //随机产生素数
int eulern = 0; //公私钥相同部分的欧拉数
Random rand = new Random();
randomprimep = 10 + rand.nextInt(200);
while (ifPrime(randomprimep)) //判断是否为素数
{
randomprimep = 10 + rand.nextInt(200);
}
randomprimeq = 10 + rand.nextInt(200);
while (ifPrime(randomprimeq)) //判断是否为素数
{
randomprimeq = 10 + rand.nextInt(200);
}
keyn = randomprimep * randomprimeq;
eulern = (randomprimep - 1) * (randomprimeq - 1);
randomprimep = randomprimeq = 0; //销毁两个随机素数
publickeye = 10 + rand.nextInt(200); //随机产生公钥
while (relativePrime(publickeye,eulern)) //判断随机公钥与公私钥相同部分的欧拉数是否为相对素数
{
publickeye = 10 + rand.nextInt(200);
}
boolean mark = true; //用简捷方法求私钥,从模逆运算原始定义出发
int k = 0;
while (mark)
{
k++;
if((k * eulern + 1)%publickeye == 0)
mark = false;
}
privatekeyd = (k * eulern + 1)/publickeye; //计算私钥
System.out.println("公钥为:(" + publickeye + "," + keyn + ")");
System.out.println("私钥为:(" + privatekeyd + "," + keyn + ")");
}
/** *//**
*判断一个整型数据是否为素数
*@param number 待判断数据
*@return true --不是素数,false -- 是素数
*/
public boolean ifPrime(int number)
{
boolean mark = false;
for (int i = 2;i < number/2 ;i++ )
{
if (number%i == 0)
{
mark = true;
break;
}
}
return mark;
}
/** *//**
*判断两个整数数据是否为素数
*@param e 整型数据
*@param n 整型数据
*@return true -- 不是否为素数,fasle -- 是互为素数
*/
public boolean relativePrime(int e,int n)
{
boolean mark = false;
for (int i = 2;i <= n ;i++ )
{
if (n%i == 0)
if (e%i == 0)
{
mark = true;
break;
}
}
return mark;
}
/** *//**
*模n的大数幂乘快速运算
*@param a 底数
*@param b 指数
*@param n 模数
*@return 大数幂乘结果
*/
public int fastPowerMultiplication(int a,int b,int n)
{
int c = 1;
while (b != 0)
{
while (b%2 == 0)
{
b = b/2;
a = ( a * a )%n;
}
b = b - 1;
c = ( c * a )%n;
}
return c;
}
/** *//**
*求一个整型数据的欧拉数
*@param number 待求欧拉数的数据
*@return 欧拉数
*/
public int getPrivateKeyexp(int number)
{
int eulernumber = 0;
for (int i = 2;i < number ;i++ )
{
if(relativePrime(i,number) == false)
{
System.out.println("相互素数:" + i + "," + number);
eulernumber++;
}
}
System.out.println(eulernumber);
return eulernumber + 1;
}
/** *//**
*对明文加密
*@param source 明文源地址
*@param destination 密文目的地
*/
public void dataEncryption(String source,String destination)
{
try
{
RandomAccessFile rafr = new RandomAccessFile(source,"r");
RandomAccessFile rafw = new RandomAccessFile(destination,"rw");
String understandtxts = "";
String passwordtxts = "";
char [] eachchar;
int charint = 0;
boolean mark = false;
try
{
long filelength = rafr.length();
long pos = 0;
while (pos != filelength)
{
understandtxts = rafr.readLine();
eachchar = understandtxts.toCharArray();
for (int i = 0 ;i < eachchar.length ;i++ )
{
charint = (int)eachchar[i];
if (charint > 127 || charint < 10)
{
System.out.println("加密失败!原文中包含不能加密的字符。");
mark = true;
break;
}
}
if (mark)
{
break;
}
pos = rafr.getFilePointer();
}
rafr.seek(0);
pos = 0;
if (!mark)
{
System.out.println("从文件读入明文:");
while (pos != filelength)
{
System.out.println(rafr.readLine());
pos = rafr.getFilePointer();
}
rafr.seek(0);
pos = 0;
System.out.println("明文加密后密文:");
while (true)
{
understandtxts = rafr.readLine();
eachchar = understandtxts.toCharArray();
for (int i = 0;i < eachchar.length ;i++ )
{
passwordtxts = passwordtxts + fastPowerMultiplication((int)eachchar[i],publickeye,keyn) + getRandomString();
}
System.out.println(passwordtxts);
rafw.writeBytes(passwordtxts);
pos = rafr.getFilePointer();
if (pos == filelength)
{
break;
}
passwordtxts = "";
rafw.writeChar(' ');
}
}
}
catch (Exception e)
{
e.printStackTrace(System.out);
}
finally
{
rafr.close();
rafw.close();
}
}
catch (IOException ex)
{
ex.printStackTrace(System.out);
}
}
/** *//**
*随机生成1~5个随机大写字母
*/
public String getRandomString()
{
Random rand = new Random();
String randstr = "";
int number = 1 + rand.nextInt(5);
int charint = 65 + rand.nextInt(26);
for (int i = 0;i < number ;i++ )
{
randstr = randstr + (char)charint;
charint = 65 + rand.nextInt(26);
}
return randstr;
}
/** *//**
*对密文解密
*@param source 密文源地址
*@param destination 明文目的址
*/
public void dataDeciphering(String source,String destination)
{
try
{
RandomAccessFile rafr = new RandomAccessFile(source,"r");
RandomAccessFile rafw = new RandomAccessFile(destination,"rw");
String understandtxts = "";
String passwordtxts = "";
char [] eachchar;
int intchar = 0;
boolean mark = false;
try
{
long filelength = rafr.length();
long pos = 0;
int j = 0;
System.out.println("密文解密后明文:");
while (true)
{
passwordtxts = rafr.readLine();
eachchar = passwordtxts.toCharArray();
for (int i = 0;i < eachchar.length ;i++ )
{
if (Character.isDigit(eachchar[i]))
{
intchar = 10*intchar + Integer.valueOf(String.valueOf(eachchar[i]));
}
else
{
j = i - 1;
if (Character.isDigit(eachchar[j]) && !Character.isDigit(eachchar[i]))
{
understandtxts = understandtxts + (char)fastPowerMultiplication(intchar,privatekeyd,keyn);
intchar = 0;
}
}
}
System.out.println(understandtxts);
rafw.writeBytes(understandtxts);
pos = rafr.getFilePointer();
if (pos == filelength)
{
break;
}
System.out.println(' ');
understandtxts = "";
}
}
catch (Exception e)
{
e.printStackTrace(System.out);
}
finally
{
rafr.close();
rafw.close();
}
}
catch (IOException ex)
{
ex.printStackTrace(System.out);
}
}
public static void main(String[] args)
{
RSA1 rsa = new RSA1();
System.out.println();
rsa.dataEncryption("D:/1.txt","D:/2.txt");
rsa.dataDeciphering("D:/2.txt","D:/3.txt");
}
}