📄 rsaencryption.java
字号:
package com.dmgc.security.cipher.unsymmetic.rsa;
import com.dmgc.security.cipher.util.*;
import java.io.*;
/**
* <p>Title: DMGC SECURITY CIPHER LIB</p>
* <p>Description: 上海信宁科技有限公司 安全密码库(JAVA version)</p>
* <p>Copyright: Copyright (c) 2003</p>
* <p>Company: 上海信宁科技有限公司</p>
* <p>RSA加密算法:主要有四种方式
* <p>对短信息的加密:这里短信息可以是会话双方的交换密钥,对于1024比特的RSA加密
* 算法短信息长度小于等于117个字节,这是因为128-3-8,减去3个标志位,减去大于等于8个
* 填空位.所得.
* <p>方法一:公钥N,E是字符串(DMGCMPINTEGER)形式,输入消息是字节数组,输出消息是字节数组
* <p>方法二:公钥N,E是文件(二进制文件)形式,输入消息是字节数组,输出消息是字节数组
* <p>对文件的加密:
* <p>1.将文件每次读取7488 (8192)字节到缓冲区
* <p>2.计算模n的大小k
* <p>3.每次选择s=k-11字节,最后一次可能S小于k-11
* <p>4.0x00 0x02作为开头两个字节 填充k-s-3个非0x00字节,再加上0x00字节,最后接上s个字节
* <p>5.加密这个k的明文消息
* <p>6.转化为大整数m
* <p>7.加密得到密文大整数c
* <p>8.恢复为字节数组,如果长度小于k,则前面填充若干个0x00,构成k长度,然后将字节数组写入输出文件
* <p>9.每次读缓存里,最后一块的填充位可能会多一些
* <p>10.通过这种方式,密文扩张约等于8%. 密文:明文=108.6%
* <p>方法三:公钥N,E是字符串(DMGCMPINTEGER)形式,输入是文件,输出是文件
* <p>方法四:公钥N,E是文件(二进制文件)形式,输入是文件,输出是文件
* @author 陆荣幸 周渊 潘勇
* @version 1.0
*/
public class RSAEncryption {
/**
* 构造函数
*/
public RSAEncryption() {
}
/**
* 测试用
* @param args
*/
public static void main(String[] args) {
RSAEncryption RSAEncryption1 = new RSAEncryption();
try {
RSAEncryption1.FileEncryptionF("D:\\lurongxing.modulus", "D:\\lurongxing.public",
"D:\\test.gz", "d:\\abc");
}
catch (IOException ex) {
ex.printStackTrace();
}
}
/**
* 生成非零填充位
* @param k 字节数组长度
* @return 非零字节数组
*/
private byte[] getPadding(int k) {
byte[] ret = new byte[k];
for (int i = 0; i < k; i++) {
ret[i] = DmgcMpInteger.getOneNonZeroByte();
}
return ret;
}
/**
* 第一种方式对短消息进行加密
* @param n RSA大整数模
* @param e RSA加密指数
* @param plainText RSA明文
* @return 返回密文字节数组
* @throws MessageTooLongException 如果消息太长,抛这个异常
*/
public byte[] MessageEncryption(String n, String e, byte[] plainText) throws
MessageTooLongException {
byte[] ret = new byte[128];
byte[] org = new byte[128];
int length = plainText.length;
if (length > 117) {
throw new MessageTooLongException("too large message");
}
// 开头两位标志位
org[0] = 0x00;
org[1] = 0x02;
int padCount = 128 - length - 3;
// 填空位
byte[] padding = getPadding(padCount);
System.arraycopy(padding, 0, org, 2, padCount);
//标志位
org[padCount + 2] = 0x00;
//明文位
System.arraycopy(plainText, 0, org, padCount + 3, length);
//加密
DmgcMpInteger ee = new DmgcMpInteger(e);
DmgcMpInteger nn = new DmgcMpInteger(n);
DmgcMpInteger ppp = new DmgcMpInteger(org);
DmgcMpInteger cc = ppp.modPow(ee, nn);
// 如果密文不是128字节也要填充0x00
byte[] temp = cc.toByteArray();
length = temp.length;
padCount = 128 - length;
if (padCount > 0) {
byte[] paddZero = new byte[padCount];
for (int i = 0; i < padCount; i++) {
paddZero[i] = 0x00;
}
System.arraycopy(paddZero, 0, ret, 0, padCount);
System.arraycopy(temp, 0, ret, padCount, length);
}
else {
System.arraycopy(temp, 0, ret, padCount, length);
}
return ret;
}
/**
* 第二种方式对短消息进行加密
* @param nfilename RSA大整数模的文件
* @param efilename RSA加密指数的文件
* @param plainText RSA明文
* @return 返回密文字节数组
* @throws MessageTooLongException 如果消息太长,抛这个异常
* @throws FileNotFoundException 如果密钥文件没有找到,抛这个异常
* @throws IOException 如果读取文件有问题,抛这个异常
*/
public byte[] MessageEncryptionF(String nfilename, String efilename,
byte[] plainText) throws
MessageTooLongException, FileNotFoundException, IOException {
byte[] ret = new byte[128];
byte[] org = new byte[128];
int length = plainText.length;
if (length > 117) {
throw new MessageTooLongException("too large message");
}
// 开头两位标志位
org[0] = 0x00;
org[1] = 0x02;
int padCount = 128 - length - 3;
// 填空位
byte[] padding = getPadding(padCount);
System.arraycopy(padding, 0, org, 2, padCount);
//标志位
org[padCount + 2] = 0x00;
//明文位
System.arraycopy(plainText, 0, org, padCount + 3, length);
//加密
// 输入文件
try {
FileInputStream fInputN = new FileInputStream(nfilename);
FileInputStream fInputE = new FileInputStream(efilename);
byte[] BufferN = new byte[128];
byte[] BufferE = new byte[128];
int lengthN = fInputN.read(BufferN);
int lengthE = fInputE.read(BufferE);
byte[] N = new byte[lengthN];
System.arraycopy(BufferN, 0, N, 0, lengthN);
byte[] E = new byte[lengthE];
System.arraycopy(BufferE, 0, E, 0, lengthE);
fInputN.close();
fInputE.close();
DmgcMpInteger ee = new DmgcMpInteger(E);
DmgcMpInteger nn = new DmgcMpInteger(N);
DmgcMpInteger ppp = new DmgcMpInteger(org);
DmgcMpInteger cc = ppp.modPow(ee, nn);
// 如果密文不是128字节也要填充0x00
byte[] temp = cc.toByteArray();
length = temp.length;
padCount = 128 - length;
if (padCount > 0) {
byte[] paddZero = new byte[padCount];
for (int i = 0; i < padCount; i++) {
paddZero[i] = 0x00;
}
System.arraycopy(paddZero, 0, ret, 0, padCount);
System.arraycopy(temp, 0, ret, padCount, length);
}
else {
System.arraycopy(temp, 0, ret, padCount, length);
}
}
catch (FileNotFoundException ex) {
throw new FileNotFoundException("file not found");
}
catch (IOException ex) {
throw new IOException("IO Exception");
}
return ret;
}
/**
* 第三方式:对文件进行加密操作
* @param n RSA大整数模
* @param e RSA加密指数
* @param inFile 要加密的文件
* @param outFile 输出的密文文件
* @return 真,操作成功,假,操作失败
* @throws FileNotFoundException 文件异常
* @throws IOException 输入输出异常
*/
public boolean FileEncryption(String n, String e, String inFile,
String outFile) throws FileNotFoundException,
IOException {
boolean ret = false;
// 加密指数 模
DmgcMpInteger ee = new DmgcMpInteger(e);
DmgcMpInteger nn = new DmgcMpInteger(n);
//
byte[] dest = new byte[128];
byte[] org = new byte[128];
byte[] temp = new byte[117];
//
byte[] buffer = new byte[7488];
int bufferLength = 0;
//
FileInputStream fInput = null;
FileOutputStream fOutput = null;
//
try {
// 输入文件
fInput = new FileInputStream(inFile);
// 输出文件
fOutput = new FileOutputStream(outFile);
//
while ( (bufferLength = fInput.read(buffer)) != -1) {
int i = 0;
for (i = 0; i < bufferLength; i = i + 117) {
// 每次读取117个字节
// 如果取到最后一次,则跳出
if (i + 117 > bufferLength) {
break;
}
// 每次117字节
System.arraycopy(buffer, i, temp, 0, 117);
// 开头两位标志位
org[0] = 0x00;
org[1] = 0x02;
int padCount = 8; //128 -length - 3;
// 填空位
byte[] padding = getPadding(padCount);
System.arraycopy(padding, 0, org, 2, padCount);
//标志位
org[padCount + 2] = 0x00;
//明文位
System.arraycopy(temp, 0, org, padCount + 3, 117);
// 加密
DmgcMpInteger ppp = new DmgcMpInteger(org);
DmgcMpInteger cc = ppp.modPow(ee, nn);
// 如果密文不是128字节也要填充0x00
byte[] tempc = cc.toByteArray();
int length = tempc.length;
padCount = 128 - length;
if (padCount > 0) {
byte[] paddZero = new byte[padCount];
// for (int j = 0; j < padCount; j++) {
// paddZero[j] = 0x00;
// }
System.arraycopy(paddZero, 0, dest, 0, padCount);
System.arraycopy(tempc, 0, dest, padCount, length);
}
else {
System.arraycopy(tempc, 0, dest, padCount, length);
}
//
fOutput.write(dest, 0, 128);
} // end for
// 如果有多余字节则进行下面操作
if ((i !=0)&& (i < bufferLength) && ( (bufferLength - i) > 0)) {
int length = bufferLength - i;
System.arraycopy(buffer, i, temp, 0, length);
byte[] temp2 = new byte[length];
System.arraycopy(temp, 0, temp2, 0, length);
// 开头两位标志位
org[0] = 0x00;
org[1] = 0x02;
int padCount = 128 - length - 3;
// 填空位
byte[] padding = getPadding(padCount);
System.arraycopy(padding, 0, org, 2, padCount);
//标志位
org[padCount + 2] = 0x00;
//明文位
System.arraycopy(temp2, 0, org, padCount + 3, length);
//加密
DmgcMpInteger ppp = new DmgcMpInteger(org);
DmgcMpInteger cc = ppp.modPow(ee, nn);
// 如果密文不是128字节也要填充0x00
byte[] tempc = cc.toByteArray();
length = tempc.length;
padCount = 128 - length;
if (padCount > 0) {
byte[] paddZero = new byte[padCount];
// for (int j = 0; j < padCount; j++) {
// paddZero[j] = 0x00;
// }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -