希望有人可以在这里为我指明正确的方向。
我对加密(Java 或其他)不是特别熟悉,但我说过我会帮助某人完成他们指定使用 RSA 加密/解密的任务。
为了让自己熟悉要完成的工作,我整理了一个小示例程序:
- 生成 6 个随机数,并将它们放在逗号分隔的字符串中
- 加密数字序列
- 将加密的数字序列附加到文件中 - 如果程序运行多次,则可以多次写入同一个文件
- 读取加密文件 - 应该获取所有已写入的序列
- 解密每个序列并打印出逗号分隔的字符串集合
这在第一次尝试时工作正常 - 即当第一个序列被写入空文件时 - 并且返回正确的数字序列。
当文件包含多个加密序列时,这会导致decrypt
例程以BadPaddingException
. 在这一点上我已经完成了一个步骤,每个byte[]
要解密的(代表一个加密的序列)都是 128 个字节,所以它不像是不规则的字节数导致了这个问题。
我知道 RSA 不再是推荐的方法,但这是我必须了解的规范。我也知道有很多关于 RSA 和 BadPaddingException 的问题,但我还没有遇到过处理这个问题的问题。
我的示例代码如下:
public class EncryptDecrypt {
private static Cipher cipher;
private static KeyPair keyPair;
public static void main(String[] args)
{
String[] numbers = getNumbers();
String numbersStr = String.join(", ", numbers);
System.out.println("Generated: " + numbersStr + ", NumBytes: " + numbersStr.getBytes().length);
byte[] encryptedNumbers = encrypt(numbersStr);
System.out.println("Encrypted: " + encryptedNumbers.toString() + ", NumBytes: " + encryptedNumbers.length);
writeToFile(encryptedNumbers);
System.out.println("Encrypted numbers written to data.txt");
ArrayList<byte[]> encryptedData = readFromFile();
System.out.println("Encrypted numbers read from data.txt, NumSequences: " + encryptedData.size());
ArrayList<String> decryptedSequences = decrypt(encryptedData);
for (int i = 0; i < decryptedSequences.size(); i++)
{
String sequence = decryptedSequences.get(i);
System.out.println("Sequence " + i + ": " + sequence);
}
}
private static String[] getNumbers()
{
String[] numbers = new String[6];
int min = 1;
int max = 60;
for (int i = 0; i < numbers.length; i++)
{
double number = (Math.random() * (max - min) + min);
numbers[i] = number >= 10 ? Integer.toString((int) number) : "0" + Integer.toString((int) number);
}
return numbers;
}
private static byte[] encrypt(String data)
{
try {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048);
keyPair = keyPairGenerator.generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
cipher.update(data.getBytes());
byte[] encrypted = cipher.doFinal();
return encrypted;
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException ex) {
Logger.getLogger(EncryptDecrypt.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
private static void writeToFile(byte[] data)
{
FileOutputStream fileOut = null;
try {
File file = new File("data.txt");
file.createNewFile();
fileOut = new FileOutputStream(file, true);
fileOut.write(data);
fileOut.flush();
fileOut.close();
} catch (FileNotFoundException ex) {
Logger.getLogger(EncryptDecrypt.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(EncryptDecrypt.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
fileOut.close();
} catch (IOException ex) {
Logger.getLogger(EncryptDecrypt.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
private static ArrayList<byte[]> readFromFile()
{
File file = new File("data.txt");
if (file.exists())
{
try {
ArrayList<byte[]> encryptedSequences = new ArrayList<>();
FileInputStream fileIn = new FileInputStream(file);
int blockSize = 128;
int numBlocks = fileIn.available() / blockSize;
for (int i = 0; i < numBlocks; i++)
{
byte[] encryptedSequence = new byte[blockSize];
fileIn.read(encryptedSequence);
encryptedSequences.add(encryptedSequence);
}
fileIn.close();
return encryptedSequences;
} catch (FileNotFoundException ex) {
Logger.getLogger(EncryptDecrypt.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(EncryptDecrypt.class.getName()).log(Level.SEVERE, null, ex);
}
}
return null;
}
private static ArrayList<String> decrypt(ArrayList<byte[]> data)
{
try {
cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
PrivateKey privateKey = keyPair.getPrivate();
cipher.init(Cipher.DECRYPT_MODE, privateKey);
ArrayList<String> decryptedStrings = new ArrayList<>();
for (byte[] sequence : data)
{
byte[] decryptedBytes = cipher.doFinal(sequence);
String decryptedString = new String(decryptedBytes);
decryptedStrings.add(decryptedString);
}
return decryptedStrings;
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException ex) {
Logger.getLogger(EncryptDecrypt.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
}
如果有人能发现这有什么问题,我将不胜感激!
谢谢