java - 使用 RC4 算法逐行加密后,解密只产生一个正确的行
问题描述
我必须使用 RC4 算法逐行加密文件。
加密整个文件并解密整个文件会产生原始文件,这很好。
当我尝试一次读取一行文件,对其进行加密,然后将加密的行写入文件时,对结果文件的解密只会产生一个正确的行,即原始文件的第一行。
我尝试使用字节数组读取文件并将其提供给 rc4 例程,该字节数组的大小是密钥长度的倍数,但结果是相同的。这是我的尝试:
try
{
BufferedReader br = new BufferedReader((new FileReader(fileToEncrypt)));
FileOutputStream fos = new FileOutputStream("C:\\Users\\nikaselo\\Documents\\Encryption\\encrypted.csv", true);
File file = new File("C:\\Users\\nikaselo\\Documents\\Encryption\\encrypted.csv");
// encrypt
while ((line = br.readLine()) != null)
{
byte [] encrypt = fed.RC4(line.getBytes(), pwd);
if (encrypt != null) dos.write(encrypt);
fos.flush();
}
fos.close();
// test decrypt
FileInputStream fis = null;
fis = new FileInputStream(file);
byte[] input = new byte[512];
int bytesRead;
while ((bytesRead = fis.read(input)) != -1)
{
byte [] de= fed.RC4(input, pwd);
String result = new String(de);
System.out.println(result);
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
这是我的 RC4 函数
public byte [] RC4 (byte [] Str, String Pwd) throws Exception
{
int[] Sbox = new int [256] ;
int A, B,c,Tmp;;
byte [] Key = {};
byte [] ByteArray = {};
//KEY
if ((Pwd.length() == 0 || Str.length == 0))
{
byte [] arr = {};
return arr;
}
if(Pwd.length() > 256)
{
Key = Pwd.substring(0, 256).getBytes();
}
else
{
Key = Pwd.getBytes();
}
//String
for( A = 0 ; A <= 255; A++ )
{
Sbox[A] = A;
}
A = B = c= 0;
for (A = 0; A <= 255; A++)
{
B = (B + Sbox[A] + Key[A % Pwd.length()]) % 256;
Tmp = Sbox[A];
Sbox[A] = Sbox[B];
Sbox[B] = Tmp;
}
A = B = c= 0;
ByteArray = Str;
for (A = 0; A <= Str.length -1 ; A++)
{
B = (B + 1) % 256;
c = (c + Sbox[B]) % 256;
Tmp = Sbox[B];
Sbox[B] = Sbox[c];
Sbox[c] = Tmp;
ByteArray[A] = (byte) (ByteArray[A] ^ (Sbox[(Sbox[B] + Sbox[c]) % 256]));
}
return ByteArray;
}
运行它给了我一条干净的线,其余的只是不可读。
解决方案
您正在逐行加密,但您正在尝试以 512 字节块进行解密。
在我看来,您的选择是:
- 在固定大小的块中加密和解密
- 将每行填充到 512 字节(并拆分长度超过 512 字节的行)
- 引入分隔符。这将很棘手,因为任何分隔符都可能出现在密文中,因此您应该对每个加密行进行 base64 编码并用换行符分隔它们。
可能 1 是最简单的(并且在真正的加密中使用的那个),但是如果你必须逐行执行,即使这会引入漏洞,我也会选择 3,但它是 RC4,无论如何它不再被认为是安全的。
推荐阅读
- ios - 在 Xcode UI Builder 上的哪里放置应用程序的启动屏幕?
- solr - Solr:重新加载查询时同义词而不重新加载集合
- django - 如何为 put 方法提供初始数据,Django(我想创建编辑个人资料页面)
- php - 6 个月后将用户状态从 0 更改为 1
- assembly - 这个对吗?
- python - 如何在 Python 列表中添加和扩展新行?
- swift - 如何在 Swift 中将对象传递给新引用
- python - 在不同时间从同一来源获取字典值并进行比较
- imagemagick - 使用 ImageMagick 从 RAW 图像中删除背景
- angular - Angular 2:将数据从服务传递到组件