为什么桌面 AES 文件 IO 与 Android AES 文件 IO 不兼容?

发布于 2024-09-26 08:56:11 字数 4019 浏览 0 评论 0原文

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

I have ported an application from Android to desktop that uses AES to encrypt some private data.
Both applications are able to encrypt and decrypt the data for their own use but unable to decrypt the other applications data.
The AES keys, IVs, and algorithms are identical.
The main difference between the two applications is that the android-sdk comes with the BouncyCastle provider already added to the security while the desktop application needed

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

Android app:

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

Desktop app:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

江心雾 2024-10-03 08:56:11

通过

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

Solved by

  1. Adding proper constructors to initialize SecretKeySpec and IvParameterSpec.
  2. Getting rid of ObjectOutputStream and ObjectInputStream in desktop app.

Android app:

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

Desktop app:

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();
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文