2013-07-07 53 views
1

我想加密/解密存储在SD卡上的我的应用程序的xml文件using this code。虽然加密工作正常,但这是我卡住的解密部分。解密SD卡上的XML文件Android

加密代码:

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

} 

解密代码:在解密方法

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) 

在这一行:

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

它抛出这个错误

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

我正确读取文件来解密它吗?

回答

0

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

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

但是,最简单的修复并不总是最好的修复。从互联网复制粘贴随机加密代码尤其值得怀疑。如果将它存储在一个文件中,绝对没有理由对密文进行十六进制编码,但是这个AdvancedCrypto类无论如何都是这样做的。以这种方式使用类还涉及到大量不必要的字节复制,如果数据增长超过几百千字节,这将很快成为性能问题。另外,请记住data is only as secure as the key。如果您在应用程序中对密钥进行硬编码,则任何有权访问应用程序的人都可以解密数据。

+0

我已经链接了quesiton中的代码:http://pocket-for-android.1047292.n5.nabble.com/Encryption-method-and-reading-the-Dropbox-backup-td4344194.html#a4454327 – input

+0

确实,我的不好。看我的编辑。 – ntoskrnl