我已将一个应用程序从 Android 移植到桌面,该应用程序使用 AES 加密一些私人数据。两个应用程序都能够加密和解密数据以供自己使用,但无法解密其他应用程序数据。AES 密钥、IV 和算法是相同的。这两个应用程序之间的主要区别在于 android-sdk 附带的 BouncyCastle 提供程序已经添加到安全性中,而桌面应用程序需要
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
安卓应用:
public class AesFileIo {
public final static String EOL = "\n";
public static final String AES_ALGORITHM = "AES/CTR/NoPadding";
public static final String PROVIDER = "BC";
private static final SecretKeySpec secretKeySpec =
new SecretKeySpec(AES_KEY_128, "AES");
private static final IvParameterSpec ivSpec = new IvParameterSpec(IV);
public String readAesFile(Context c, String fileName) {
StringBuilder stringBuilder = new StringBuilder();
try {
InputStream is = c.openFileInput(fileName);
Cipher cipher = Cipher.getInstance(AES_ALGORITHM, PROVIDER);
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivSpec);
CipherInputStream cis = new CipherInputStream(is, cipher);
InputStreamReader isr = new InputStreamReader(cis);
BufferedReader reader = new BufferedReader(isr);
String line;
while ((line = reader.readLine()) != null) {
stringBuilder.append(line).append(EOL);
}
is.close();
} catch (java.io.FileNotFoundException e) {
// OK, file probably not created yet
Log.i(this.getClass().toString(), e.getMessage(), e);
} catch (Exception e) {
Log.e(this.getClass().toString(), e.getMessage(), e);
}
return stringBuilder.toString();
}
public void writeAesFile(Context c, String fileName, String theFile) {
try {
Cipher cipher = Cipher.getInstance(AES_ALGORITHM, PROVIDER);
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivSpec);
byte[] encrypted = cipher.doFinal(theFile.getBytes());
OutputStream os = c.openFileOutput(fileName, 0);
os.write(encrypted);
os.flush();
os.close();
} catch (Exception e) {
Log.e(this.getClass().toString(), e.getMessage(), e);
}
}
}
桌面应用:
public class AesFileIo {
private static final String EOL = "\n";
private static final String AES_ALGORITHM = "AES/CTR/NoPadding";
private static final SecretKeySpec secretKeySpec =
new SecretKeySpec(AES_KEY_128, "AES");
private static final IvParameterSpec ivSpec = new IvParameterSpec(IV);
public void AesFileIo() {
Security.addProvider(new org.bouncycastle.jce.provider
.BouncyCastleProvider());
}
public String readFile(String fileName) {
StringBuilder stringBuilder = new StringBuilder();
try {
ObjectInputStream is = new ObjectInputStream(
new FileInputStream(fileName));
Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivSpec);
CipherInputStream cis = new CipherInputStream(is, cipher);
InputStreamReader isr = new InputStreamReader(cis);
BufferedReader reader = new BufferedReader(isr);
String line;
while ((line = reader.readLine()) != null) {
stringBuilder.append(line).append(EOL);
}
is.close();
} catch (java.io.FileNotFoundException e) {
System.out.println("FileNotFoundException: probably OK");
} catch (Exception e) {
e.printStackTrace();
}
return stringBuilder.toString();
}
public void writeFile(String fileName, String theFile) {
try {
Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivSpec);
byte[] encrypted = cipher.doFinal(theFile.getBytes());
ObjectOutputStream os = new ObjectOutputStream(
new FileOutputStream(fileName));
os.write(encrypted);
os.flush();
os.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}