2010-10-05 27 views
4

我已经将应用程序从Android移植到使用AES加密某些私人数据的桌面。 这两个应用程序都能够加密和解密数据以供自己使用,但无法解密其他应用程序数据。 AES密钥,IV和算法是相同的。 两个应用程序之间的主要区别是,Android的SDK附带已经添加到安全性,同时在桌面应用程序所需为什么桌面AES文件IO与Android AES文件IO不兼容?

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

Android应用的BouncyCastle的供应商:

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

回答

3

解决了

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