4

我已将一个应用程序从 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();
        }
    }
}
4

1 回答 1

3

解决者

  1. 添加适当的构造函数来初始化 SecretKeySpec 和 IvParameterSpec。
  2. 摆脱桌面应用程序中的 ObjectOutputStream 和 ObjectInputStream。

安卓应用:

public class AesFileIo {
    private static final String EOL = "\n";
    private static final String AES_ALGORITHM = "AES/CTR/NoPadding";
    private SecretKeySpec secretKeySpec;
    private IvParameterSpec ivSpec;
    private static final String PROVIDER = "BC"; 

    AesFileIo(byte[] aesKey, byte[] iv) {
        ivSpec = new IvParameterSpec(iv);
        secretKeySpec = new SecretKeySpec(aesKey, "AES");
    }

    public String readFile(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 writeFile(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 SecretKeySpec secretKeySpec;
    private IvParameterSpec ivSpec;

    AesFileIo(byte[] aesKey, byte[] iv) {
        Security.addProvider(new org.bouncycastle.jce.provider
                .BouncyCastleProvider());
        ivSpec = new IvParameterSpec(iv);
        secretKeySpec = new SecretKeySpec(aesKey, "AES");
    }

    public String readFile(String fileName) {
        StringBuilder stringBuilder = new StringBuilder();
        try {
            FileInputStream fis = new FileInputStream(fileName);
            Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivSpec);
            CipherInputStream cis = new CipherInputStream(fis, cipher);
            InputStreamReader isr = new InputStreamReader(cis);
            BufferedReader reader = new BufferedReader(isr);
            String line;
            while ((line = reader.readLine()) != null) {
                stringBuilder.append(line).append(EOL);
            }
            fis.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());
            FileOutputStream fos = new FileOutputStream(fileName);
            fos.write(encrypted);
            fos.flush();
            fos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
于 2010-10-06T14:14:27.027 回答