2013-05-09 2 views
4

Я пытаюсь сохранить некоторые зашифрованные данные в файловой системе Android. Я получаю ошибки, которые я не понимаю и пустые файлы. Пожалуйста помоги.Cipher Output и Input Streams

Код:

private Cipher cipher; 
private ArrayList<ConnectionProfile> connectionProfiles; 

public void createCipher() throws Exception{ 
    cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
} 

public void saveProfiles() { 
    try { 
     if (cipher == null) {createCipher();} 
     FileOutputStream fos = openFileOutput("connProfiles.bin", Context.MODE_PRIVATE); 
     BufferedOutputStream bos = new BufferedOutputStream(fos); 
     CipherOutputStream cos = new CipherOutputStream(bos, cipher); 
     ObjectOutputStream oos = new ObjectOutputStream(cos); 
     oos.writeObject(connectionProfiles); 
     oos.flush(); 
     oos.close(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

public void readProfiles() { 
    try { 
     if (cipher == null) {createCipher();} 
     FileInputStream fis = openFileInput("connProfiles.bin"); 
     BufferedInputStream bis = new BufferedInputStream(fis); 
     CipherInputStream cis = new CipherInputStream(bis, cipher); 
     ObjectInputStream ois = new ObjectInputStream(cis); 
     connectionProfiles = (ArrayList<ConnectionProfile>) ois.readObject(); 
     ois.close(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
     ; 
    } 
} 

Traceback:

05-09 23:24:39.628: W/System.err(837): java.lang.IllegalStateException 
05-09 23:24:39.639: W/System.err(837): at javax.crypto.Cipher.update(Cipher.java:884) 
05-09 23:24:39.639: W/System.err(837): at javax.crypto.CipherOutputStream.write(CipherOutputStream.java:95) 
05-09 23:24:39.639: W/System.err(837): at java.io.DataOutputStream.writeShort(DataOutputStream.java:192) 
05-09 23:24:39.648: W/System.err(837): at java.io.ObjectOutputStream.writeStreamHeader(ObjectOutputStream.java:1815) 
05-09 23:24:39.648: W/System.err(837): at java.io.ObjectOutputStream.<init>(ObjectOutputStream.java:279) 
05-09 23:24:39.648: W/System.err(837): at com.sajnasoft.down2home.MainActivity.saveProfiles(MainActivity.java:39) 
05-09 23:24:39.648: W/System.err(837): at com.sajnasoft.down2home.MainActivity$2.onClick(MainActivity.java:92) 
05-09 23:24:39.658: W/System.err(837): at android.view.View.performClick(View.java:4204) 
05-09 23:24:39.658: W/System.err(837): at android.view.View$PerformClick.run(View.java:17355) 
05-09 23:24:39.658: W/System.err(837): at android.os.Handler.handleCallback(Handler.java:725) 
05-09 23:24:39.658: W/System.err(837): at android.os.Handler.dispatchMessage(Handler.java:92) 
05-09 23:24:39.658: W/System.err(837): at android.os.Looper.loop(Looper.java:137) 
05-09 23:24:39.668: W/System.err(837): at android.app.ActivityThread.main(ActivityThread.java:5041) 
05-09 23:24:39.668: W/System.err(837): at java.lang.reflect.Method.invokeNative(Native Method) 
05-09 23:24:39.668: W/System.err(837): at java.lang.reflect.Method.invoke(Method.java:511) 
05-09 23:24:39.678: W/System.err(837): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) 
05-09 23:24:39.678: W/System.err(837): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) 
05-09 23:24:39.678: W/System.err(837): at dalvik.system.NativeStart.main(Native Method) 
05-09 23:26:33.878: W/IInputConnectionWrapper(837): showStatusIcon on inactive InputConnection 

Update:

Так что теперь у меня есть

private Spinner spinner; 
private SpinAdapter adapter; 
private Cipher cipher; 
private ArrayList<ConnectionProfile> connectionProfiles; 
private KeyGenerator keygen; 
private SecretKey key; 

public void createCipher() throws Exception{ 
    cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
    keygen = KeyGenerator.getInstance("AES"); 
    key = keygen.generateKey(); 
} 

public void saveProfiles() { 
    try { 
     if (cipher == null) {createCipher();} 
     cipher.init(Cipher.ENCRYPT_MODE, key); 
     FileOutputStream fos = openFileOutput("connProfiles.bin", Context.MODE_PRIVATE); 
     BufferedOutputStream bos = new BufferedOutputStream(fos); 
     CipherOutputStream cos = new CipherOutputStream(bos, cipher); 
     ObjectOutputStream oos = new ObjectOutputStream(cos); 
     oos.writeObject(connectionProfiles); 
     oos.flush(); 
     oos.close(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

public void readProfiles() { 
    try { 
     if (cipher == null) {createCipher();} 
     cipher.init(Cipher.ENCRYPT_MODE, key); 
     FileInputStream fis = openFileInput("connProfiles.bin"); 
     BufferedInputStream bis = new BufferedInputStream(fis); 
     CipherInputStream cis = new CipherInputStream(bis, cipher); 
     ObjectInputStream ois = new ObjectInputStream(cis); 
     connectionProfiles = (ArrayList<ConnectionProfile>) ois.readObject(); 
     ois.close(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
     ; 
    } 
} 

и:

05-11 22:20:40.658: W/System.err(1019): java.io.StreamCorruptedException 
05-11 22:20:40.658: W/System.err(1019):  at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:2109) 
05-11 22:20:40.658: W/System.err(1019):  at java.io.ObjectInputStream.<init>(ObjectInputStream.java:372) 
05-11 22:20:40.658: W/System.err(1019):  at com.sajnasoft.down2home.MainActivity.readProfiles(MainActivity.java:59) 
05-11 22:20:40.658: W/System.err(1019):  at com.sajnasoft.down2home.MainActivity.onCreate(MainActivity.java:83) 
05-11 22:20:40.658: W/System.err(1019):  at android.app.Activity.performCreate(Activity.java:5104) 
05-11 22:20:40.658: W/System.err(1019):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080) 
05-11 22:20:40.668: W/System.err(1019):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144) 
05-11 22:20:40.668: W/System.err(1019):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230) 
05-11 22:20:40.668: W/System.err(1019):  at android.app.ActivityThread.access$600(ActivityThread.java:141) 
05-11 22:20:40.668: W/System.err(1019):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234) 
05-11 22:20:40.668: W/System.err(1019):  at android.os.Handler.dispatchMessage(Handler.java:99) 
05-11 22:20:40.668: W/System.err(1019):  at android.os.Looper.loop(Looper.java:137) 
05-11 22:20:40.668: W/System.err(1019):  at android.app.ActivityThread.main(ActivityThread.java:5041) 
05-11 22:20:40.678: W/System.err(1019):  at java.lang.reflect.Method.invokeNative(Native Method) 
05-11 22:20:40.678: W/System.err(1019):  at java.lang.reflect.Method.invoke(Method.java:511) 
05-11 22:20:40.678: W/System.err(1019):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) 
05-11 22:20:40.678: W/System.err(1019):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) 
05-11 22:20:40.678: W/System.err(1019):  at dalvik.system.NativeStart.main(Native Method) 

Хорошо, теперь я инициализирую шифр и соль в onCreate, и мои методы значительно усложнились следующим образом. Конечный результат - это поврежденный поток при попытке прочитать.

private Spinner spinner; 
private SpinAdapter adapter; 
private Cipher cipher; 
private ArrayList<ConnectionProfile> connectionProfiles; 
private KeyGenerator keygen; 
private SecretKey key; 
private String salt; 
private SecretKey saltedKey; 
private static final String RANDOM_ALGORITHM = "SHA1PRNG"; 
private IvParameterSpec ivSpec; 

public void createKey() throws Exception { 
    keygen = KeyGenerator.getInstance("AES"); 
    key = keygen.generateKey(); 
    byte[] saltedKeyBytes = new byte[key.getEncoded().length+salt.getBytes().length]; 
    System.arraycopy(key.getEncoded(), 0, saltedKeyBytes, 0, key.getEncoded().length); 
    System.arraycopy(salt.getBytes(), 0, saltedKeyBytes, key.getEncoded().length, salt.getBytes().length); 
    saltedKey = new SecretKeySpec(saltedKeyBytes, 0, saltedKeyBytes.length, "AES"); 
} 

private byte[] generateIv() throws NoSuchAlgorithmException { 
     SecureRandom random = SecureRandom.getInstance(RANDOM_ALGORITHM); 
     byte[] iv = new byte[16]; 
     random.nextBytes(iv); 
     return iv; 
} 

public void saveProfiles() { 
    try { 
     if (key == null) {createKey();} 
     cipher.init(Cipher.ENCRYPT_MODE, saltedKey, ivSpec); 
     FileOutputStream fos = openFileOutput("connProfiles.bin", Context.MODE_PRIVATE); 
     BufferedOutputStream bos = new BufferedOutputStream(fos); 
     CipherOutputStream cos = new CipherOutputStream(bos, cipher); 
     ObjectOutputStream oos = new ObjectOutputStream(cos); 
     oos.writeObject(connectionProfiles); 
     oos.flush(); 
     oos.close(); 
     FileOutputStream keyOutputStream = openFileOutput("key.bin", Context.MODE_PRIVATE); 
     keyOutputStream.write(key.getEncoded()); 
     keyOutputStream.flush(); 
     keyOutputStream.close(); 
     byte[] iv = generateIv(); 
     IvParameterSpec ivSpec = new IvParameterSpec(iv); 
     FileOutputStream ivOutputStream = openFileOutput("iv.bin", Context.MODE_PRIVATE); 
     ivOutputStream.write(iv); 
     ivOutputStream.flush(); 
     ivOutputStream.close(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

public void readProfiles() { 
    try { 
     File file = new File(this.getFilesDir(), "key.bin"); 
     byte[] keyBytes = new byte[(int) file.length()]; 
     FileInputStream keyInputStream = new FileInputStream(file); 
     keyInputStream.read(keyBytes); 
     keyInputStream.close(); 
     File file2 = new File(this.getFilesDir(), "iv.bin"); 
     byte[] iv = new byte[(int) file2.length()]; 
     FileInputStream ivInputStream = new FileInputStream(file2); 
     ivInputStream.read(iv); 
     ivInputStream.close(); 
     IvParameterSpec ivSpec = new IvParameterSpec(iv); 
     byte[] saltedKeyBytes = new byte[keyBytes.length+salt.getBytes().length]; 
     System.arraycopy(keyBytes, 0, saltedKeyBytes, 0, keyBytes.length); 
     System.arraycopy(salt.getBytes(), 0, saltedKeyBytes, keyBytes.length, salt.getBytes().length); 
     saltedKey = new SecretKeySpec(saltedKeyBytes, 0, saltedKeyBytes.length, "AES"); 
     cipher.init(Cipher.DECRYPT_MODE, saltedKey, ivSpec); 
     FileInputStream fis = openFileInput("connProfiles.bin"); 
     BufferedInputStream bis = new BufferedInputStream(fis); 
     CipherInputStream cis = new CipherInputStream(bis, cipher); 
     ObjectInputStream ois = new ObjectInputStream(cis); 
     connectionProfiles = (ArrayList<ConnectionProfile>) ois.readObject(); 
     ois.close(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
     ; 
    } 
} 

Traceback:

05-19 01:08:17.325: W/System.err(843): java.io.StreamCorruptedException 
05-19 01:08:17.325: W/System.err(843): at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:2109) 
05-19 01:08:17.325: W/System.err(843): at java.io.ObjectInputStream.<init>(ObjectInputStream.java:372) 
05-19 01:08:17.335: W/System.err(843): at com.sajnasoft.down2home.MainActivity.readProfiles(MainActivity.java:102) 
05-19 01:08:17.335: W/System.err(843): at com.sajnasoft.down2home.MainActivity.onCreate(MainActivity.java:132) 
05-19 01:08:17.335: W/System.err(843): at android.app.Activity.performCreate(Activity.java:5104) 
05-19 01:08:17.335: W/System.err(843): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080) 
05-19 01:08:17.335: W/System.err(843): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144) 
05-19 01:08:17.335: W/System.err(843): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230) 
05-19 01:08:17.335: W/System.err(843): at android.app.ActivityThread.access$600(ActivityThread.java:141) 
05-19 01:08:17.335: W/System.err(843): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234) 
05-19 01:08:17.345: W/System.err(843): at android.os.Handler.dispatchMessage(Handler.java:99) 
05-19 01:08:17.345: W/System.err(843): at android.os.Looper.loop(Looper.java:137) 
05-19 01:08:17.345: W/System.err(843): at android.app.ActivityThread.main(ActivityThread.java:5041) 
05-19 01:08:17.345: W/System.err(843): at java.lang.reflect.Method.invokeNative(Native Method) 
05-19 01:08:17.345: W/System.err(843): at java.lang.reflect.Method.invoke(Method.java:511) 
05-19 01:08:17.345: W/System.err(843): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) 
05-19 01:08:17.345: W/System.err(843): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) 
05-19 01:08:17.355: W/System.err(843): at dalvik.system.NativeStart.main(Native Method) 

ответ

2

Хорошо, я получил это работает. Вы не используете правильную инициализацию ivSpec для шифрования. Попробуйте это (iv теперь поле):

public void saveProfiles() { 
    try { 
     if (key == null) { 
      createKey(); 
      iv = generateIv(); 
      ivSpec = new IvParameterSpec(iv); 
     } 
     cipher.init(Cipher.ENCRYPT_MODE, saltedKey, ivSpec); 
     FileOutputStream fos = openFileOutput("connProfiles.bin", Context.MODE_PRIVATE); 
     BufferedOutputStream bos = new BufferedOutputStream(fos); 
     CipherOutputStream cos = new CipherOutputStream(bos, cipher); 
     ObjectOutputStream oos = new ObjectOutputStream(cos); 
     oos.writeObject(connectionProfiles); 
     oos.flush(); 
     oos.close(); 
     FileOutputStream keyOutputStream = openFileOutput("key.bin", Context.MODE_PRIVATE); 
     keyOutputStream.write(key.getEncoded()); 
     keyOutputStream.flush(); 
     keyOutputStream.close(); 
     FileOutputStream ivOutputStream = openFileOutput("iv.bin", Context.MODE_PRIVATE); 
     ivOutputStream.write(iv); 
     ivOutputStream.flush(); 
     ivOutputStream.close(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

В моем тесте я не пользовался солью. Это может вызвать проблемы, если ключ слишком длинный.

+0

Нет, я убедился, что ключ + соль 256 бит – sajattack

+0

в порядке, тогда код, который я написал, должен работать ... –

+0

Попытка его сейчас ... – sajattack

1

Я думаю, что проблема вы забыли инициализации шифра: Вы должны сказать шифровать, что зашифровать или расшифровать: cipher.init (Cipher.DECRYPT_MODE, secKey) ; cipher.init (Cipher.ENCRYPT_MODE, secKey);

Я думаю, что AES нужен ключ для шифрования и дешифрования.

Надежда эта ссылка может помочь:

http://www.flexiprovider.de/examples/ExampleCrypt.html

+0

Итак, теперь у меня есть экономия, но с трудом читается. Возможно, он создает другой ключ/шифр, когда я читаю. Я обновлю свой OP. – sajattack

+0

Может ли это поставить под угрозу мою безопасность, если бы я сохранил ключ в файле в том же месте, что и зашифрованный файл? – sajattack

+0

Первый. Как я знаю, вы должны использовать тот же ключ для шифрования и дешифрования. Чтобы написать свой ключ в файле, я думаю, что все в порядке. Но я думаю, вы должны добавить символ после того, как прочитаете из файла. Например, ваш ключ: «ThisIsKey_: D». Вы можете сохранить значение ключа: «ThisIsKey», и после его чтения из файла вы можете добавить «_: D», чтобы сделать свой ключ. Надеюсь, он поможет – gZerone