1

我正在尝试使用此代码加密/解密存储在 sd 卡上的应用程序的 xml 文件。虽然加密工作正常,但我被困在解密部分。

加密代码:

private void writeToFile(final String xmlString, final String exportFileName) throws IOException {
  File dir = new File(Environment.getExternalStorageDirectory(), BData.DATASUBDIRECTORY);
  if (!dir.exists()) {
     dir.mkdirs();
  }
  File file = new File(dir, exportFileName);
  file.createNewFile();

  BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
  try {
      String fileData = AdvancedCrypto.encrypt("myPassword", "mySalt"), xmlString.toString());
      bos.write(fileData.getBytes());
  }  catch (Exception e){
  } finally {
      if (bos != null) {
          bos.flush();
          bos.close();
      }
  }

}

解密代码:

   public void getDataFromXML(Context context, String fileName){
       try
       {
           XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
           factory.setNamespaceAware(true);
           XmlPullParser _xml = factory.newPullParser();

            // get a reference to the file.
           File file = new File(Environment.getExternalStorageDirectory()
                    + File.separator + fileName);

            // create an input stream to be read by the stream reader.
           FileInputStream fis = new FileInputStream(file);

           BufferedInputStream buf = new BufferedInputStream(fis);

           int size = (int) file.length();
           byte[] contents = new byte[size];
           //byte[] data = buf.read(contents);

           String fileData = AdvancedCrypto.decrypt("myPassword", "mySalt"), contents.toString());
           buf.read(fileData.getBytes());

            // set the input for the parser using an InputStreamReader
           _xml.setInput(buf, HTTP.UTF_8);

           buf.close();

           int eventType = _xml.getEventType();
           boolean done = false;       

           //..rest of the code
           }
    }

它抛出这个错误:

07-07 21:44:27.755: W/System.err(5608): Caused by: java.lang.StringIndexOutOfBoundsException: length=11; regionStart=0; regionLength=32
07-07 21:44:27.755: W/System.err(5608):     at java.lang.String.startEndAndLength(String.java:593)
07-07 21:44:27.755: W/System.err(5608):     at java.lang.String.substring(String.java:1474)

在解密方法的这一行:

String ivHex = encrypted.substring(0, IV_LENGTH * 2);

我是否正确读取文件以解密它?

4

1 回答 1

0

数组不会覆盖 Java 中的 toString() 方法。在字节数组上调用 toString() 可能不会产生你想要的。

AdvancedCrypto.decrypt()方法期望密文为字符串。相应的encrypt方法似乎对输出字节进行十六进制编码。对您的代码最简单的修复方法是更改contents.toString()​​为new String(contents). (请注意,依赖平台默认编码是不好的做法——在任一方向的字符串和字节之间进行转换时,您应该明确指定 UTF-8。)

然而,最简单的修复并不总是最好的。从互联网上复制粘贴随机密码尤其值得怀疑。如果您将密文存储在文件中,绝对没有理由对密文进行十六进制编码,但是这个 AdvancedCrypto 类无论如何都会这样做。以这种方式使用该类还涉及大量不必要的字节复制,如果您的数据增长超过几百千字节,这将很快成为性能问题。

另外,请记住,数据仅与密钥一样安全。如果您在应用程序中对密钥进行硬编码,则有权访问该应用程序的任何人都可以解密数据。

于 2013-07-07T18:56:40.263 回答