/* * Copyright 2012 The Stanford MobiSocial Laboratory * * 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 org.mobisocial.corral; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.CipherInputStream; import javax.crypto.CipherOutputStream; import javax.crypto.IllegalBlockSizeException; import javax.crypto.KeyGenerator; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; import javax.crypto.ShortBufferException; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.mobisocial.corral.CorralHelper.DownloadProgressCallback; import org.mobisocial.corral.CorralHelper.DownloadProgressCallback.DownloadChannel; import org.mobisocial.corral.CorralHelper.DownloadProgressCallback.DownloadState; import org.mobisocial.corral.CorralHelper.UploadProgressCallback; import mobisocial.musubi.util.Base64; import android.util.Log; public class CryptUtil { int blocksize = 16; int bufsize = 65536; Cipher encCipher = null; Cipher decCipher = null; byte[] buf = new byte[blocksize]; byte[] obuf = new byte[512]; byte[] key = null; byte[] IV = null; String keystr = null; long length = 0; String md5 = null; long mLastCheckedForCancellation; public CryptUtil() throws NoSuchAlgorithmException{ KeyGenerator kgen = KeyGenerator.getInstance("AES"); SecureRandom sr = SecureRandom.getInstance("SHA1PRNG"); kgen.init(128, sr); SecretKey skey = kgen.generateKey(); key = skey.getEncoded(); keystr = Base64.encodeToString(key, false); IV = new byte[blocksize]; } public CryptUtil(String mykey){ key = Base64.decode(mykey); keystr= mykey; IV = new byte[blocksize]; } public String getKey(){ // Log.e("KEY", keystr); // Log.e("HASH", ""+keystr.hashCode()); return keystr; } public long getLength(){ return length; } public String getMd5(){ return md5; } public void InitCiphers() throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchProviderException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException{ encCipher = Cipher.getInstance("AES/CBC/PKCS5Padding", "BC"); SecretKey keyValue = new SecretKeySpec(key,"AES"); AlgorithmParameterSpec IVspec = new IvParameterSpec(IV); encCipher.init(Cipher.ENCRYPT_MODE, keyValue, IVspec); decCipher = Cipher.getInstance("AES/CBC/PKCS5Padding", "BC"); decCipher.init(Cipher.DECRYPT_MODE, keyValue, IVspec); } public void ResetCiphers() { encCipher=null; decCipher=null; } public void encrypt(InputStream fis, OutputStream fos, UploadProgressCallback callback) throws IOException, ShortBufferException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException { fis = new BufferedInputStream(fis); fis = new CipherInputStream(fis, encCipher); fos = new BufferedOutputStream(fos); byte[] buf = new byte[bufsize]; int len = 0; length = 0; md5 = null; MessageDigest md = MessageDigest.getInstance("MD5"); checkUserCancellation(callback); while ((len = fis.read(buf)) != -1) { checkUserCancellation(callback); fos.write(buf,0,len); md.update(buf,0,len); length += len; } byte[] b = md.digest(); md5 = Base64.encodeToString(b, false); fos.close(); fis.close(); Log.e("MD5", md5); } void checkUserCancellation(UploadProgressCallback callback) throws IOException { long now = System.currentTimeMillis(); if (now - mLastCheckedForCancellation > CorralHelper.CANCEL_SAMPLE_WINDOW) { if (callback.isCancelled()) { throw new IOException("User cancelled transfer"); } mLastCheckedForCancellation = now; } } public void decrypt(InputStream fis, OutputStream fos, long total, DownloadProgressCallback callback) throws IOException, ShortBufferException, IllegalBlockSizeException, BadPaddingException { DownloadChannel channel = DownloadChannel.SERVER; callback.onProgress(DownloadState.TRANSFER_IN_PROGRESS, channel, 0); byte[] buf = new byte[bufsize]; int len = 0; fis = new BufferedInputStream(fis); fos = new BufferedOutputStream(fos); fos = new CipherOutputStream(fos, decCipher); int read = 0; int progress = 0; while ((len = fis.read(buf)) != -1) { read += len; int newProgress = Math.round(100f * read / total); if (progress != newProgress) { progress = newProgress; callback.onProgress(DownloadState.TRANSFER_IN_PROGRESS, channel, progress); } fos.write(buf,0,len); } fos.close(); fis.close(); } }