Android Studio

[안드로이드] android file AES 암호화 복호화

i-moo 2017. 5. 11. 18:34
반응형

Assets 폴더에 있는 이미지 파일을 디바이스에 저장한다.

InputStream으로 byte를 받아와 한 번 태워 암호화를 시킨다. 

// Assets 폴더의 filename 파일을 열어 저장
InputStream inputStream = assetManager.open(fileName, AssetManager.ACCESS_BUFFER);
int fileSize = inputStream.available();

byte[] tempData
= new byte[fileSize];

inputStream.read(tempData);
inputStream.close();

byte[] data = new SecretFile().encodeFile("Key", tempData);

outFile.createNewFile();
FileOutputStream fileOutputStream = new FileOutputStream(outFile);
fileOutputStream.write(data);
fileOutputStream.close();

암호화 함수 호출 : byte[] data = new SecretFile().encodeFile("Key", tempData);

암호화 해주는 함수...

public static byte[] encodeFile(String key, byte[] fileData) throws Exception
{
// key.getBytes() : InvalidKeyException: Key length not 128/192/256 bits. 에러
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec); // ENCRYPT_MODE 암호화 모드에 초기화

byte[] encrypted = cipher.doFinal(fileData);

return encrypted;
}

파일을 암호화 해서 저장하면 '내 파일'로 들어가서 디바이스 상에서는 이미지가 나오지 않는다.

복호화를 하여 이미지를 이미지 뷰에 띄워보도록 하쟈!

복호화도 InputStream에서 byte를 받아 한 번 태워 복호화 한 byte를 사용한다.

InputStream inputStream = new FileInputStream(path);
int fileSize = inputStream.available();

byte[] tempData
= new byte[fileSize];

Log.i("AES", "tempData 사이즈 : " + tempData.length);
inputStream.read(tempData);

byte[] data = new SecretFile().decodeFile("Key", tempData);
Log.i("AES", "data 사이즈 : " + data.length);

Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
imageView.setImageBitmap(bitmap);
//imageView.setImageDrawable(Drawable.createFromStream(inputStream, null));
inputStream.close();

복호화 함수 호출 : byte[] data = new SecretFile().decodeFile("Key", tempData);

복호화 해주는 함수...

public static byte[] decodeFile(String key, byte[] fileData) throws Exception
{
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); ///ECB/NoPadding"); ///ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);

byte[] decrypted = cipher.doFinal(fileData); // BadPaddingException 예외처리. 이유? 키가 다르거나 AES 키 크기가 맞지 않을때.

return decrypted;
}

==== 추가 ====

복호화 해줄 때에 이번 프로젝트 같은 경우에는 암호화가 안된 파일도 사용할 때가 많았다.

상위 코드는 같은 키로 암호화된 파일만 복호화가 정상적으로 작동하여 프로그램이 정상적으로 작동하였고,

암호화가 안된 파일 같은 경우는 복호화가 비정상적으로 작동하여 프로그램이 원하는대로 작동하지 않았다.

암호화가 안된 파일을 구별하는 방법을 찾아보았지만 원하는 딱 나오는 답은 찾을 수 없었고,

복호화 할 때에 예외처리 나는 경우 받았던 byte를 그대로 return해주는 방법을 선택하였다.

그렇다면, 암호화가 안된 파일은 예외처리가 날 것이고, 예외처리가 나면 복호화를 시도 하지 않는 그 원래의 byte로 파일을 처리할 수 있기에 

원하는 대로 작동 시킬 수 있게 되었다.


    public byte[] decodeFile(String key, byte[] fileData)

    {

        byte[] decrypted = fileData;

try {

        SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(), "AES");

        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");  ///ECB/NoPadding");  ///ECB/PKCS5Padding");

        cipher.init(Cipher.DECRYPT_MODE, skeySpec);

decrypted = cipher.doFinal(fileData); // BadPaddingException 예외처리. 이유? 키가 다르거나 AES 키 크기가 맞지 않을때.

} catch (IllegalBlockSizeException e) {

// TODO Auto-generated catch block

e.printStackTrace();

decrypted = fileData;

} catch (BadPaddingException e) {

// TODO Auto-generated catch block

e.printStackTrace();

decrypted = fileData;

} catch (NoSuchAlgorithmException e) {

// TODO Auto-generated catch block

e.printStackTrace();

decrypted = fileData;

} catch (NoSuchPaddingException e) {

// TODO Auto-generated catch block

e.printStackTrace();

decrypted = fileData;

} catch (InvalidKeyException e) {

// TODO Auto-generated catch block

e.printStackTrace();

decrypted = fileData;

}


        return decrypted;

    }

반응형