2013-05-09 3 views
4

일부 암호화 된 데이터를 Android 파일 시스템에 저장하려고합니다. 내가 이해하지 못하는 파일이나 빈 파일을 가져 오는 중입니다. 도와주세요.암호 출력 및 입력 스트림

코드 :

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

역 추적 :

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 

업데이트 :

그래서

지금은

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

하고 있습니다

,536,913,632 10
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(); 
     ; 
    } 
} 

역 추적 : 당신은 암호화되고, 암호 또는 암호 해독하는 데 알려야합니다 :

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

좋아, 내가 작업을 얻었다. Cipher 초기화에 올바른 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

ok, 게시 된 코드가 작동해야합니다 ... –

+0

지금 시도 중 ... – sajattack

1

나는 문제는 암호 초기화하기 위해서 잊어 생각 cipher.init을 (cipher를 Cipher.DECRYPT_MODE, secKey) ; cipher.init (Cipher.ENCRYPT_MODE, secKey);

AES는 암호화하고 해독 할 키가 필요하다고 생각합니다. 이 링크가 도움이 될 수 있습니다

희망 :

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

+0

그래서 지금은 절약하고 있지만 읽는 데 어려움이 있습니다. 아마도 내가 읽을 때 다른 키/암호를 생성하고있을 것입니다. 나는 영업을 갱신 할 것이다. – sajattack

+0

암호화 된 파일과 동일한 위치에있는 파일에 키를 저장하면 보안이 침해됩니까? – sajattack

+0

먼저. 아시다시피 암호화 및 암호 해독에 동일한 키를 사용해야합니다. 파일에 키를 쓰려면 괜찮다고 생각합니다. 하지만 파일을 읽은 후에 어떤 인물을 추가해야한다고 생각합니다. 키의 예는 "ThisIsKey_ : D"입니다. 키 값은 "ThisIsKey"를 저장하고 파일에서 읽은 후에 "_ : D"를 추가하여 키를 만들 수 있습니다. 희망 도움이 – gZerone