我正在开发游戏,我已经成功地使用整数数组实现了保存文件的功能,并通过这些整数将内容添加回我的游戏中。现在,我想对其进行加密,以使玩家不能只是进入文本文件并更改整数以将其放入游戏中的任何位置。我已经弄清楚了,我认为除了ivBytes初始化及其初始化方式是什么: 代码:包管理器;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.ShortBufferException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import Data.SaveData;
import GameStates.LevelSelector;
import Inventory.Inventory;
public class ResourceManager {
private byte[] keyBytes;
private byte[] ivBytes;
private byte[] input;
private SecretKeySpec key;
private IvParameterSpec ivSpec;
private Cipher cipher;
public ResourceManager() {
String keypass = "DAA5885FD1118E34FB7DC4F58500392DBD30D00E63B2DCF120A7A97300D0E44B";
keyBytes = keypass.getBytes();
key = new SecretKeySpec(keyBytes, 0, keyBytes.length, "DES");
ivSpec = new IvParameterSpec(ivBytes);
try {
cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
}
}
public void saveFile(SaveData data) {
String saveData = "";
for (int i = 0; i < data.getSaveData().length; i++) {
saveData += "" + data.getSaveData()[i] + " ";
}
input = saveData.getBytes();
try {
cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
}
byte[] encrypted = new byte[cipher.getOutputSize(input.length)];
try {
int enc_len = cipher.update(input, 0, input.length, encrypted, 0);
enc_len += cipher.doFinal(encrypted, enc_len);
} catch (ShortBufferException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
String encryptedData = new String(encrypted);
try (BufferedWriter saveCreator = new BufferedWriter(new FileWriter(new File("./saveData/" + data.getFileName() + ".txt")))){
saveCreator.write(encryptedData, 0, encryptedData.length());
saveCreator.flush();
saveCreator.close();
} catch (IOException x) {
System.err.format("IOException: %s%n", x);
}
}
public void loadFile(String fileName) {
try (BufferedReader saveReader = new BufferedReader(new FileReader(new File("./saveData/" + fileName + ".txt")))){
String data = saveReader.readLine();
saveReader.close();
try {
cipher.init(Cipher.DECRYPT_MODE, key, ivSpec);
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
}
byte[] encrypted = data.getBytes();
int enc_len = cipher.update(input, 0, input.length, encrypted, 0);
byte[] decrypted = new byte[cipher.getOutputSize(enc_len)];
int dec_len = cipher.update(encrypted, 0, enc_len, decrypted, 0);
dec_len += cipher.doFinal(decrypted, dec_len);
String newdata = new String(decrypted);
String tokens[] = newdata.split("\\s+");
int[] realdata = new int[tokens.length];
for (int i = 0; i < tokens.length; i++) {
realdata[i] = Integer.parseInt(tokens[i]);
}
Main.Main.currentWorld = realdata[0];
Main.Main.currentLevel = realdata[1];
Main.Main.unlockedWorld = realdata[2];
Main.Main.unlockedLevel = realdata[3];
LevelUtility.LevelMap.player.setLives(realdata[4]);
LevelUtility.LevelMap.player.setInventory(new Inventory(320, 240));
for (int i = 5; i < realdata.length; i = i + 2) {
if (i != realdata.length - 1) {
LevelUtility.LevelMap.player.getInventory().addItem(realdata[i], realdata[i+1]);
}
}
Main.Main.gsm.addState(new LevelSelector());
Main.Main.gsm.setState("LevelSelectorWorld1");
} catch (IOException x) {
System.err.format("IOException: %s%n", x);
} catch (ShortBufferException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
}
}
我当前的错误是在声明IVParameterSpec时出现空指针异常,因为ivBytes没有初始化,我也不知道如何初始化它。感谢您的帮助。
完全错误:
Exception in thread "handledThread: 1" java.lang.NullPointerException at javax.crypto.spec.IvParameterSpec.<init>(IvParameterSpec.java:53) at Managers.ResourceManager.<init>(ResourceManager.java:38) at GameStates.PauseScreen.selectOption(PauseScreen.java:85) at GameStates.PauseScreen.tick(PauseScreen.java:72) at Managers.GameStateManager.tick(GameStateManager.java:39) at Main.Main.tick(Main.java:127) at Main.Main.run(Main.java:89) at Utility.handledThread.run(handledThread.java:26)
答案 0 :(得分:0)
IV可以初始化为块大小的任何字节数组,对于DES为8字节。但是为了安全起见,IV应该是随机字节,并且每次加密都不同。 IV可以放在加密数据的前面,不需要保密。
DES有一个8字节的密钥(仅使用56位),因此没有必要提供更长的密钥。
但是,不要使用DES,它不是安全的,使用AES的,它并不难使用且安全。
AES的使用与DES完全相同,但有以下区别:块大小和IV为16字节,共有三种密钥大小:128、192或256位。