/* * Copyright (c) 2013 Allogy Interactive. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package com.allogy.encryption; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.util.Random; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.spec.SecretKeySpec; import android.content.Context; import android.util.Log; import android.widget.Toast; import com.allogy.app.util.Util; public class EncryptFile { private static final String LOG_TAG = EncryptFile.class.getName(); public static SecretKeySpec matchKeyToFile(String fileName, Context enccon) { String fileOut = ""; SecretKeySpec key = null; try { if (fileName.compareTo("") == 0) { throw new KeyGenFailException( KeyGenFailException.failureTypes.EMPTY_FIELD); } String seed = makeRandomFileName(); fileOut = Util.ENCRYPTED_DIRECTORY + Util.getFileNameFromPath(fileName); String keyFileName = Util.KEY_DIRECTORY + fileName; KeyTools kTool = new KeyTools(); key = kTool.makeKey(keyFileName, seed, LOG_TAG); if (key == null) throw new KeyGenFailException( KeyGenFailException.failureTypes.KEY_NULL); else { kTool.saveKey(key, Util.KEY_DIRECTORY, fileName, LOG_TAG, enccon); } // if(!encact.getComponentName().getClassName().equals(EncryptedEditActivity.class)){ encryptFile(fileName, fileOut, key, enccon); // } } catch (KeyGenFailException e) { String msg = null; if (e.fail == KeyGenFailException.failureTypes.KEY_NULL) { msg = "Was unable to generate a key!"; Log.e(LOG_TAG, msg); Toast.makeText(enccon, msg, Toast.LENGTH_SHORT).show(); } if (e.fail == KeyGenFailException.failureTypes.DATABASE_ERROR) { msg = "Corrupted value for directory in databse."; Log.e(LOG_TAG, msg); Toast.makeText(enccon, msg, Toast.LENGTH_SHORT).show(); } if (e.fail == KeyGenFailException.failureTypes.EMPTY_FIELD) { msg = "Please enter a file name to encrypt."; Toast.makeText(enccon, msg, Toast.LENGTH_SHORT).show(); } Toast.makeText( enccon, "Successfuly encrypted \"" + fileName + "\" as \"" + " \"" + fileOut + " \" ", Toast.LENGTH_SHORT).show(); } return key; } public static String makeRandomFileName() { // Create random value generator Random gen = new Random(System.currentTimeMillis()); // A character in java is two bytes, so this will be a string between 1 // and 15 characters long int stringSize = 1 + gen.nextInt(15) * 2; gen.setSeed(System.currentTimeMillis()); // Set to new seed String output = ""; int nInt = 0; for (int i = 0; i < stringSize; i++) { nInt = gen.nextInt(75) + 48; while (nInt == 33 || nInt == 34 || nInt == 124 || nInt == 92 || nInt == 62 || nInt == 63 || nInt == 42 || nInt == 58 || nInt == 43 || nInt == 91 || nInt == 93 || nInt == 47 || nInt == 39) // A reserved character -> "|\\?*<\":>+[]/'" nInt = gen.nextInt(75) + 48; output += String.valueOf((char) nInt); } return output; } public static void encryptFile(String fileInName, String fileOutName, SecretKeySpec key, Context enccon) { Log.i(LOG_TAG, fileInName); Log.i(LOG_TAG, fileOutName); FileInputStream input = null; FileOutputStream output = null; Cipher encCipher = null; try { encCipher = Cipher.getInstance("AES"); encCipher.init(Cipher.ENCRYPT_MODE, key); File fileIn = new File(fileInName); if (fileIn.length() > Integer.MAX_VALUE) throw new FileTooBigException("File\'" + fileInName + "\' is too large too encrypt."); input = new FileInputStream(fileIn); //partition the file into pieces, each 5Mb in size int sizeOf5MB = 5242880; int num_of_files = ((int) fileIn.length() / sizeOf5MB) + 1; for(int i = 0; i < num_of_files; i++){ byte[] plainText = new byte[sizeOf5MB]; input.read(plainText, 0 , sizeOf5MB); byte[] encrypted = encCipher.doFinal(plainText); output = new FileOutputStream(new File(fileOutName + "_part"+ i + ".enc")); output.write(encrypted); Log.i(LOG_TAG, "encrypted: " + fileOutName + "_part" + i); } } catch (BadPaddingException e) { Log.e(LOG_TAG, e.getMessage()); } catch (UnsupportedEncodingException e) { Log.e(LOG_TAG, e.getMessage()); } catch (IllegalBlockSizeException e) { Log.e(LOG_TAG, e.getMessage()); } catch (FileTooBigException e) { Log.e(LOG_TAG, e.getMessage()); Toast.makeText(enccon, "Was unable to encrypt file \'" + fileInName + "\' is too large too encrypt.", Toast.LENGTH_SHORT); } catch (IOException ioe) { Log.e(LOG_TAG, ioe.getMessage()); Toast.makeText(enccon, "Was unable to encrypt file \'" + fileInName + "\'.", Toast.LENGTH_SHORT); } catch (NoSuchAlgorithmException e) { Log.e(LOG_TAG, e.getMessage()); } catch (NoSuchPaddingException e) { Log.e(LOG_TAG, e.getMessage()); } catch (InvalidKeyException e) { Log.e(LOG_TAG, e.getMessage()); } finally { if (input != null) try { input.close(); } catch (IOException e) { Log.e(LOG_TAG, "Cannot close input stream!"); e.printStackTrace(); } if (output != null) try { output.close(); } catch (IOException e) { Log.e(LOG_TAG, "Cannot close output stream!"); e.printStackTrace(); } } }// End encryptFile }