Почему ввод-вывод файла AES несовместим с вводом-выводом файла Android AES? - PullRequest
4 голосов
/ 05 октября 2010

Я перенес приложение с Android на настольный компьютер, которое использует AES для шифрования некоторых личных данных. Оба приложения могут шифровать и дешифровать данные для собственного использования, но не могут дешифровать данные других приложений. Ключи AES, IV и алгоритмы идентичны. Основное различие между этими двумя приложениями состоит в том, что android-sdk поставляется с поставщиком BouncyCastle, уже добавленным в систему безопасности, в то время как настольному приложению требуется

Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

Android-приложение:

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();
        }
    }
}

1 Ответ

3 голосов
/ 06 октября 2010

Решено с помощью

  1. Добавление правильных конструкторов для инициализации SecretKeySpec и IvParameterSpec.
  2. Избавление от ObjectOutputStream и ObjectInputStream в настольном приложении.

Android-приложение:

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();
        }
    }
}
...