Java ECB模式下的RSA加密
我的代码有问题 我试图做的是使用ECB模式加密一个文件(意思是,加密文本块而不链接到下一个块) 它有时工作得很好,但有时却不行。当它加密128字节的数据并写入129字节时,问题就出现了。直到第一次这样做,它都会工作得很好,但是解密会被关闭一个字节,并且会把一切搞得一团糟。我知道这一点,因为当它出错时,您可以看到密码(在第88行,一个字节数组)的长度是129,而不是128,然后它被写入文件 这里有一个例子来说明我的意思: 加密: 测试 测试 测试 测试 测试 输出: 测试 测试 测试 测试 testtest(500字节的混乱数据) 我已经附上了我的全部代码;为了快速运行,我已经启用了加密后立即生成到标准输出的解密 因此,只需运行: -k密钥(将生成key.public和key.private) -public-i输入-o输出(将加密一些文件输入并将其存储在输出中,读取该文件,解密它,发送到标准输出) 任何帮助都将不胜感激Java ECB模式下的RSA加密,java,encryption,rsa,ecb,Java,Encryption,Rsa,Ecb,我的代码有问题 我试图做的是使用ECB模式加密一个文件(意思是,加密文本块而不链接到下一个块) 它有时工作得很好,但有时却不行。当它加密128字节的数据并写入129字节时,问题就出现了。直到第一次这样做,它都会工作得很好,但是解密会被关闭一个字节,并且会把一切搞得一团糟。我知道这一点,因为当它出错时,您可以看到密码(在第88行,一个字节数组)的长度是129,而不是128,然后它被写入文件 这里有一个例子来说明我的意思: 加密: 测试 测试 测试 测试 测试 输出: 测试 测试 测试 测试 tes
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Scanner;
import java.io.*;
import java.util.List;
import java.util.Random;
public class RSA {
public static void main(String[] args) throws UnsupportedEncodingException {
List<String> list = Arrays.asList(args);
if(list.contains("-h")) {
System.out.println("Usage:");
System.out.println("RSA -h - View command-line arguments.");
System.out.println("RSA -k <key file> -b <bit size> - Generate public/private keyfiles of size <bit size>.");
System.out.println("RSA -e <key file>.public -i <input file> -o <output file> - Encrypt <input file> with key <key file>, store in <output file>.");
System.out.println("RSA -d <key file>.private -i <input file> -o <output file> - Decrypt <input file> with key <key file>, store in <output file>.");
} else if (list.contains("-k")) {
String key_file = "";
try {
key_file = list.get(list.indexOf("-k") + 1);
if(key_file.equals("-b")) {
System.out.println("Usage:");
System.out.println("RSA -k <key file> -b <bit size> - Generate public/private keyfiles of size <bit size>.");
System.exit(1);
}
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Usage:");
System.out.println("RSA -k <key file> -b <bit size> - Generate public/private keyfiles of size <bit size>.");
System.exit(1);
}
int bit_size = 0;
if(!list.contains("-b")) {
bit_size = 1024;
} else {
try {
bit_size = Integer.parseInt(list.get(list.indexOf("-b") + 1));
} catch(ArrayIndexOutOfBoundsException e) {
System.out.println("Usage:");
System.out.println("RSA -k <key file> -b <bit size> - Generate public/private keyfiles of size <bit size>.");
System.exit(1);
}
}
generate_key(bit_size, key_file);
} else if (list.contains("-e")) {
//get input file and output file
String input_file = "";
String key_file = "";
String output_file = "";
try {
input_file = list.get(list.indexOf("-i") + 1);
output_file = list.get(list.indexOf("-o") + 1);
key_file = list.get(list.indexOf("-e") + 1);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Usage:");
System.out.println("RSA -e <key file>.public -i <input file> -o <output file> - Encrypt <input file> with key <key file>, store in <output file>.");
System.exit(1);
}
String public_key = read_file(key_file);
String private_key = read_file("key.private");
BigInteger public_modulus = new BigInteger(public_key.substring(1, public_key.indexOf(',')));
BigInteger public_exponent = new BigInteger(public_key.substring(public_key.indexOf(',') + 1, public_key.length() - 1));
byte[] file = read_bytes(input_file);
byte[] cipher = new byte[128];
byte[] decrypted = new byte[128];
BigInteger d = new BigInteger(private_key.substring(1, private_key.indexOf(',')));
BigInteger modulus = new BigInteger(private_key.substring(private_key.indexOf(',') + 1, private_key.length() - 1));
write_file(output_file, "", false);
int index = 0;
while (index<file.length) {
byte[] block = Arrays.copyOfRange(file, index, index+128);
cipher = new BigInteger(block).modPow(public_exponent, public_modulus).toByteArray();
append_bytes(output_file, cipher);
index+=128;
}
byte[] encrypted = read_bytes(output_file);
index = 0;
while(index < encrypted.length) {
byte[] block = Arrays.copyOfRange(encrypted, index, index+256);
decrypted = new BigInteger(block).modPow(d, modulus).toByteArray();
System.out.println(new String(decrypted));
index+= 256;
}
} else if (list.contains("-d")) {
/*String input_file, output_file, key_file;
input_file = output_file = key_file = "";
try {
input_file = list.get(list.indexOf("-i") + 1);
output_file = list.get(list.indexOf("-o") + 1);
key_file = list.get(list.indexOf("-d") + 1);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Usage:");
System.out.println("RSA -d <key file>.private -i <input file> -o <output file> - Decrypt <input file> with key <key file>, store in <output file>.");
System.exit(1);
}
String private_key = read_file(key_file).toString();
BigInteger d = new BigInteger(private_key.substring(1, private_key.indexOf(',')));
BigInteger modulus = new BigInteger(private_key.substring(private_key.indexOf(',') + 1, private_key.length() - 1));
byte[] encrypted = null;
/* todo */
} else {
System.out.println("Usage:");
System.out.println("RSA -h - View command-line arguments.");
System.out.println("RSA -k <key file> -b <bit size> - Generate public/private keyfiles of size <bit size>.");
System.out.println("RSA -e <key file>.public -i <input file> -o <output file> - Encrypt <input file> with key <key file>, store in <output file>.");
System.out.println("RSA -d <key file>.private -i <input file> -o <output file> - Decrypt <input file> with key <key file>, store in <output file>.");
}
}
private static void generate_key(int bit_size, String key_file) {
BigInteger p = BigInteger.probablePrime(bit_size, new Random());
BigInteger q = BigInteger.probablePrime(bit_size, new Random());
BigInteger one = new BigInteger("1");
BigInteger phi = new BigInteger("1");
BigInteger e = new BigInteger("65537");
boolean done = false;
while(!done) {
BigInteger temp = p.subtract(one);
BigInteger temp2 = q.subtract(one);
phi = (temp.multiply(temp2));
if(phi.gcd(e).equals(one)) {
done = true;
} else {
e = BigInteger.probablePrime(bit_size, new Random());
}
}
BigInteger public_modulus = p.multiply(q);
BigInteger public_exponent = e;
BigInteger private_key = public_exponent.modInverse(phi); //d
try {
write_file(key_file + ".public", "(" + public_modulus + "," + e + ")", false);
write_file(key_file + ".private", "(" + private_key.toString() + "," + public_modulus + ")", false);
} catch (Exception ex) {
System.out.println("Error creating key files.");
System.exit(1);
}
}
public static void write_bytes(String file_name, byte[] bytes) {
try {
FileOutputStream fos = new FileOutputStream(new File(file_name));
fos.write(bytes);
fos.close();
} catch (IOException e) {
System.out.println("Error writing bytes to file.");
System.exit(1);
}
}
public static String read_file(String file_name) {
boolean is_key = false;
if(file_name.contains(".public") || file_name.contains(".private"))
is_key = true;
Scanner sc = null;
try {
sc = new Scanner (new File(file_name));
} catch (FileNotFoundException e) {
System.out.println("Input file does not exist.");
System.exit(1);
}
StringBuilder buf = new StringBuilder("");
while (sc.hasNext ()) {
buf.append (sc.nextLine());
if(!is_key)
buf.append("\n");
}
sc.close();
return buf.toString();
}
public static byte[] read_bytes(String file_name) {
Path path = Paths.get(file_name);
byte[] encrypted = null;
try {
encrypted = Files.readAllBytes(path);
} catch (IOException e) {
System.out.println("Error reading bytes from " + file_name);
System.exit(1);
}
return encrypted;
}
public static void append_bytes(String file_name, byte[] bytes) {
try {
OutputStream fos = new FileOutputStream(file_name, true);
fos.write(bytes);
fos.flush();
fos.close();
} catch (IOException e) {
e.printStackTrace();
System.out.println("Error appending bytes to file.");
System.exit(1);
}
}
public static void write_file(String file_name, String message, boolean append) {
try {
FileWriter fstream = new FileWriter(file_name, append);
BufferedWriter out = new BufferedWriter(fstream);
out.write(message);
out.close();
} catch (Exception e){
System.out.println("Error writing to file.");
System.exit(1);
}
}
}
导入java.io.File;
导入java.io.FileNotFoundException;
导入java.io.FileOutputStream;
导入java.io.IOException;
导入java.io.UnsupportedEncodingException;
导入java.math.biginger;
导入java.nio.file.Files;
导入java.nio.file.Path;
导入java.nio.file.path;
导入java.util.array;
导入java.util.Scanner;
导入java.io.*;
导入java.util.List;
导入java.util.Random;
公共类RSA{
公共静态void main(字符串[]args)引发UnsupportedEncodingException{
List=Arrays.asList(args);
if(list.contains(“-h”)){
System.out.println(“用法:”);
System.out.println(“RSA-h-View命令行参数”);
println(“RSA-k-b-生成大小相同的公钥/私钥文件”);
System.out.println(“RSA-e.public-i-o-Encrypt with key,store in.”);
System.out.println(“RSA-d.private-i-o-Decrypt with key,store in.”);
}else if(list.contains(“-k”)){
字符串键_file=“”;
试一试{
key_file=list.get(list.indexOf(“-k”)+1);
if(key_file.equals(“-b”)){
System.out.println(“用法:”);
println(“RSA-k-b-生成大小相同的公钥/私钥文件”);
系统出口(1);
}
}捕获(阵列索引边界外异常e){
System.out.println(“用法:”);
println(“RSA-k-b-生成大小相同的公钥/私钥文件”);
系统出口(1);
}
int bit_size=0;
如果(!list.contains(“-b”)){
比特大小=1024;
}否则{
试一试{
bit_size=Integer.parseInt(list.get(list.indexOf(“-b”)+1));
}捕获(阵列索引边界外异常e){
System.out.println(“用法:”);
println(“RSA-k-b-生成大小相同的公钥/私钥文件”);
系统出口(1);
}
}
生成密钥(位大小、密钥文件);
}else if(list.contains(“-e”)){
//获取输入文件和输出文件
字符串输入_file=“”;
字符串键_file=“”;
字符串输出_file=“”;
试一试{
input_file=list.get(list.indexOf(“-i”)+1);
output_file=list.get(list.indexOf(“-o”)+1);
key_file=list.get(list.indexOf(“-e”)+1);
}捕获(阵列索引边界外异常e){
System.out.println(“用法:”);
System.out.println(“RSA-e.public-i-o-Encrypt with key,store in.”);
系统出口(1);
}
字符串public\u key=read\u file(key\u file);
String private_key=读取_文件(“key.private”);
biginger public_module=新的biginger(public_key.substring(1,public_key.indexOf(','));
BigInteger公共指数=新的BigInteger(public_key.substring(public_key.indexOf(',)+1,public_key.length()-1));
字节[]文件=读取字节(输入文件);
字节[]密码=新字节[128];
字节[]解密=新字节[128];
BigInteger d=新的BigInteger(private_key.substring(1,private_key.indexOf(','));
BigInteger模数=新的BigInteger(private_key.substring(private_key.indexOf(','))+1,private_key.length()-1));
写入_文件(输出_文件“”,false);
int指数=0;
而(指数ECB是一个。是一个,不是一个
通常,您会使用:为对称密码选择一个随机密钥,例如,使用对称密码加密消息,然后使用RSA加密对称密钥
另外,请记住使用适当的填充方案,例如在使用RSA加密密钥时;未添加的“教科书式RSA”是不安全的(或者使用不需要填充的方案)对于AES,也不要使用ECB模式;使用语义安全模式,如CBC或CTR,或者更好的是,使用模式。这是一个作业,而不是我计划使用的东西。不过,谢谢!@Bobby:如果是这样的话,我会说这要么是一个愚蠢的作业,要么你误解了它的要求,但这确实是一件愚蠢的事情o、 关于KEM的有趣链接,但我确实认为将实现留给任何人都有点太棘手了。特别是关于在0和模N之间生成随机M的那一行似乎很棘手,我不能100%确定是否创建一个随机的小一点的doe