I've never worked with encryption before. Actually I know nothing about encryption. I have a file encrypted with openssl tool using params:
openssl aes-256-cbc -nosalt -in fileIn -out fileOUT -p -k KEY
I need to decrypt it into memory but I don't know how. Can anyone provide me the code related to encryption?
Here's class I have written to decrypt a string encoded with params above (if I remmeber it correct):
public class CipherUtils {
public static byte[] getKey(String password, byte[] salt) {
try {
byte[] passwordSalt = EncodingUtils.getAsciiBytes(password);
passwordSalt = concatenateByteArrays(passwordSalt, salt);
byte[] hash1 = getHashForHash(null, passwordSalt);
byte[] hash2 = getHashForHash(hash1, passwordSalt);
byte[] key = concatenateByteArrays(hash1, hash2);
return key;
} catch (Exception e) {
return null;
}
}
public static byte[] getIV(String password, byte[] salt) {
try {
byte[] passwordSalt = EncodingUtils.getAsciiBytes(password);
passwordSalt = concatenateByteArrays(passwordSalt, salt);
byte[] hash1 = getHashForHash(null, passwordSalt);
byte[] hash2 = getHashForHash(hash1, passwordSalt);
byte[] hash3 = getHashForHash(hash2, passwordSalt);
return hash3;
} catch (Exception e) {
return null;
}
}
private static byte[] getHashForHash(byte[] hash, byte[] passwordSalt) {
try {
byte[] hashMaterial = concatenateByteArrays(hash, passwordSalt);
MessageDigest md = MessageDigest.getInstance("MD5");
return md.digest(hashMaterial);
} catch (Exception e) {
return null;
}
}
private static byte[] concatenateByteArrays(byte[] a, byte[] b) {
if (a == null)
return b;
if (b == null)
return a;
byte[] result = new byte[a.length + b.length];
System.arraycopy(a, 0, result, 0, a.length);
System.arraycopy(b, 0, result, a.length, b.length);
return result;
}
}
Salt is an empty bytearray in this case. It uses apache-commons-compress.jar.
Here's usage example:
byte[] key = CipherUtils.getKey(password, null);
byte[] IV = CipherUtils.getIV(password, null);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "AES"),
new IvParameterSpec(IV));
cis = new CipherInputStream(is, cipher);
Where is is an InputStream of encrypted data.
this may helps you
public void encrypt() throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
// Here you read the cleartext.
FileInputStream fis = new FileInputStream("data/cleartext");
// This stream write the encrypted text. This stream will be wrapped by
// another stream.
FileOutputStream fos = new FileOutputStream("data/encrypted");
// Length is 16 byte
SecretKeySpec sks = new SecretKeySpec("yourkey".getBytes(), "AES");
// Create cipher
Cipher cipher = Cipher.getInstance("AES/CBC");
cipher.init(Cipher.ENCRYPT_MODE, sks);
// Wrap the output stream
CipherOutputStream cos = new CipherOutputStream(fos, cipher);
// Write bytes
int b;
byte[] d = new byte[8];
while ((b = fis.read(d)) != -1) {
cos.write(d, 0, b);
}
// Flush and close streams.
cos.flush();
cos.close();
fis.close();
}
Decrypt
public void decrypt() throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
FileInputStream fis = new FileInputStream("data/encrypted");
FileOutputStream fos = new FileOutputStream("data/decrypted");
SecretKeySpec sks = new SecretKeySpec("yourkey".getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC");
cipher.init(Cipher.DECRYPT_MODE, sks);
CipherInputStream cis = new CipherInputStream(fis, cipher);
int b;
byte[] d = new byte[8];
while((b = cis.read(d)) != -1) {
fos.write(d, 0, b);
}
fos.flush();
fos.close();
cis.close();
}
Related
I am creating an application with content security for no one could ever copy the contents and files. I am using cipher to encrypt the image directly from the URL, with out downloading to the device.
Please find my code below.
URL url = new URL(images.getImageurl());
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setDoOutput(true);
File folder = new File(Environment.getExternalStorageDirectory(), "zerb");
boolean success = true;
if (!folder.exists()){
folder.mkdirs();
}
InputStream fis = connection.getInputStream();
String path = folder.getAbsolutePath() + "images.getImageName + ".jpg";
encryptfile(fis, path, AppConstants.password + images.getContentid() + images.getTopicid())
fis.close();
And the cipher encryption Method code is
private static boolean encryptfile(InputStream inputStream, String path, String password) throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
FileOutputStream fos = new FileOutputStream(path.concat(".crypt"));
byte[] key = (AppConstants.salt + password).getBytes("UTF-8");
MessageDigest sha = MessageDigest.getInstance("SHA-1");
key = sha.digest(key);
key = Arrays.copyOf(key, 16);
SecretKeySpec sks = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, sks);
CipherOutputStream cos = new CipherOutputStream(fos, cipher);
int b;
byte[] d = new byte[8];
while ((b = inputStream.read(d)) != -1) {
cos.write(d, 0, b);
}
cos.flush();
cos.close();
inputStream.close();
File encryptedFile = new File(path.concat(".crypt"));
return (encryptedFile.exists());
}
and the decryption code is
public static void decrypt(String path, String password, String outPath) throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
FileInputStream fis = new FileInputStream(path);
FileOutputStream fos = new FileOutputStream(outPath);
byte[] key = (AppConstants.salt + password).getBytes("UTF-8");
MessageDigest sha = MessageDigest.getInstance("SHA-1");
key = sha.digest(key);
key = Arrays.copyOf(key, 16);
SecretKeySpec sks = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, sks);
CipherInputStream cis = new CipherInputStream(fis, cipher);
int b;
byte[] d = new byte[8];
while ((b = cis.read(d)) != -1) {
fos.write(d, 0, b);
}
fos.flush();
fos.close();
cis.close();
}
If I decrypt the image, it will be shown and can be copied from the device.
All I need is to load the encrypted image to an ImageView without saving the decrypted image to the device, so that no one can copy. Please someone help me.
An ImageView can show an in-memory android.graphics.Bitmap which can be read in directly from an InputStream.
For example, the decrypt() method could be adapted to return a Bitmap :
public Bitmap decrypt(String path, String password) throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
FileInputStream fis = new FileInputStream(path);
byte[] key = (AppConstants.salt + password).getBytes("UTF-8");
MessageDigest sha = MessageDigest.getInstance("SHA-1");
key = sha.digest(key);
key = Arrays.copyOf(key, 16);
SecretKeySpec sks = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, sks);
CipherInputStream cis = new CipherInputStream(fis, cipher);
Bitmap bitmap = BitmapFactory.decodeStream(cis);
cis.close();
return bitmap;
}
(Although it's called Bitmap, it's fine to decode a .jpg or .png).
Then this can be shown in the ImageView:
ImageView imageView = findViewById(R.id.imageView);
Bitmap bitmap = decrypt(path + ".crypt", password);
imageView.setImageBitmap(bitmap);
I am implementing encryption/decryption to my files. code is given below. I can't find out the problem.
Am I missing anything? I need to implement 128 bit AES Encryption.
Is there anything wrong?
It end up with error
"javax.crypto.BadPaddingException: error:1e06b065:Cipher functions:EVP_DecryptFinal_ex:BAD_DECRYPT"
Please help me.
private static byte[] encodeFile(byte[] yourKey, byte[] fileData)
throws Exception {
byte[] encrypted = null;
SecretKeySpec skeySpec = new SecretKeySpec(yourKey, 0, yourKey.length, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7PADDING");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
encrypted = cipher.doFinal(fileData);
return encrypted;
}
private static byte[] generateKey() throws NoSuchAlgorithmException {
byte[] keyStart = "This is my key".getBytes();
String id = "dummypass";
int iterationCount = 1000;
int saltLength = 32;
int keyLength = 128;
SecureRandom random = new SecureRandom();
byte[] salt = Arrays.copyOf(keyStart,saltLength);
random.nextBytes(salt);
KeySpec keySpec = new PBEKeySpec(id.toCharArray(), salt,
iterationCount, keyLength);
SecretKeyFactory keyFactory = SecretKeyFactory
.getInstance("PBKDF2WithHmacSHA1");
byte[] keyBytes = new byte[0];
try {
keyBytes = keyFactory.generateSecret(keySpec).getEncoded();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
SecretKey key = new SecretKeySpec(keyBytes, "AES");
return key.getEncoded();
}
private static byte[] decodeFile(byte[] yourKey, byte[] encryptedData)
throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(yourKey, 0, yourKey.length,
"AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7PADDING");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] decrypted = cipher.doFinal(encryptedData);
return decrypted;
}
public static void Encrypt(byte[] bytesToEncrypt, File target) {
try {
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream(target));
byte[] key = generateKey();
byte[] encryptedBytes = encodeFile(key, bytesToEncrypt);
bos.write(encryptedBytes);
bos.flush();
bos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
public static byte[] DecryptFile(byte[] bytesToDecrypt) {
byte[] decodedData = new byte[0];
try {
byte[] key = generateKey();
decodedData = decodeFile(key, bytesToDecrypt);
} catch (Exception e) {
e.printStackTrace();
}
return decodedData;
}
Verify that key is the same in both Encrypt and DecryptFile.
Since both call generateKey and generateKey calls SecureRandom nextBytes the keys are going to be different.
You need to save the encryption key for use during decryption.
Till kitkat, encryption/decryption is working good but in lollipop it decrypts only partial data.
I don't have problem with encryption because I encrypted a file with lollipop and decrypts it with kitkat it works fine but not vice versa.
Here is the code.
Encryption code
Encrypt(BufferedInputStream is, File destfile, String passcode) {
bis = is;
try {
fos = new FileOutputStream(destfile);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
dest = new BufferedOutputStream(fos, 1024);
this.passcode = passcode;
}
static void encrypt() throws IOException, NoSuchAlgorithmException,
NoSuchPaddingException, InvalidKeyException {
// Length is 16 byte
SecretKeySpec sks = new SecretKeySpec(passcode.getBytes(), "AES");
// Create cipher
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, sks);
// Wrap the output stream
CipherOutputStream cos = new CipherOutputStream(fos, cipher);
// Write bytes
int b;
byte[] d = new byte[1024];
while ((b = bis.read(d)) != -1) {
cos.write(d, 0, b);
}
// Flush and close streams.
cos.flush();
cos.close();
bis.close();
}
Decryption code
public Decrypt(String path, String pathcode) {
// TODO Auto-generated constructor stub
filepath = path;
try {
fis = new FileInputStream(new File(path));
this.passcode = pathcode;
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
static String decrypt() throws IOException, NoSuchAlgorithmException,
NoSuchPaddingException, InvalidKeyException {
SecretKeySpec sks = new SecretKeySpec(passcode.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, sks);
CipherInputStream cis = new CipherInputStream(fis, cipher);
int size = fis.available();
byte[] resdata = new byte[size];
cis.read(resdata, 0, size);
String newres = new String(resdata, "UTF-8").trim();
//write("decrypted_file.xhtml",newres);
if(fis!=null)
{
fis.close();
}
if(cis!=null)
cis.close();
return newres;
}
What's the problem in this code? Do I need to do anything more?
available() doesn't necessarily return the length of the entire stream, just the estimated number of bytes that can be read without blocking. So, use a ByteArrayOutputStream to store the bytes and then covert to a byte array:
CipherInputStream cis = new CipherInputStream(fis, cipher);
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int bytesRead;
byte[] data = new byte[1024];
while ((bytesRead = cis.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, bytesRead);
}
buffer.flush();
byte[] resdata = buffer.toByteArray();
String newres = new String(resdata, "UTF-8").trim();
I Tried following code.
How to read encrypted .epub file (Without saving decrypted file on sd card)
I want to maintain security for .epub file
is it possible to maintain security?
Thanks for Help in prior
static void encrypt() throws IOException, NoSuchAlgorithmException,
NoSuchPaddingException, InvalidKeyException {
// Here you read the cleartext.
String file_en_path = Environment.getExternalStorageDirectory().getAbsolutePath() +"/Decrypted";
File extStore = new File(file_en_path,"text.epub");
FileInputStream fis = new FileInputStream(extStore);
// This stream write the encrypted text. This stream will be wrapped by
// another stream.
File extStore_enc = new File(file_en_path,"text_enc.epub");
FileOutputStream fos = new FileOutputStream(extStore_enc);
Log.d("encrypt--fis------------->>>>>>",""+fis);
Log.d("encrypt--fos------------->>>>>>",""+fos);
// Length is 16 byte
SecretKeySpec sks = new SecretKeySpec("MyDifficultPassw".getBytes(),"AES");
// Create cipher
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, sks);
// Wrap the output stream
CipherOutputStream cos = new CipherOutputStream(fos, cipher);
// Write bytes
int b;
byte[] d = new byte[8];
while ((b = fis.read(d)) != -1) {
cos.write(d, 0, b);
}
// Flush and close streams.
cos.flush();
cos.close();
fis.close();
}
static void decrypt() throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
String file_de_path = Environment.getExternalStorageDirectory().getAbsolutePath() +"/Decrypted";
File extStore = new File(file_de_path,"text_enc.epub");
//File extStore = Environment.getExternalStorageDirectory();
FileInputStream fis = new FileInputStream(extStore);
File extStore_dec = new File(file_de_path,"text_dec.epub");
FileOutputStream fos = new FileOutputStream(extStore_dec);
//FileOutputStream fos = context.openFileOutput("fontsize_dec.txt",Context.MODE_PRIVATE);
Log.d("decrypt--fis------------->>>>>>",""+fis);
Log.d("decrypt--fos------------->>>>>>",""+fos);
SecretKeySpec sks = new SecretKeySpec("MyDifficultPassw".getBytes(),"AES");
IvParameterSpec ivSpec = new IvParameterSpec("MyDifficultPassw".getBytes());
Cipher cipher = Cipher.getInstance("AES");
try {
cipher.init(Cipher.DECRYPT_MODE, sks, ivSpec);
} catch (InvalidAlgorithmParameterException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
CipherInputStream cis = new CipherInputStream(fis, cipher);
int b;
byte[] d = new byte[8];
StringBuilder sb = new StringBuilder();
String line;
BufferedReader reader = new BufferedReader(new InputStreamReader(cis, "UTF-8"));
/*line = reader.readLine();
sb.append(line);
Log.d("sb.append(line)--------------------------->",""+sb.append(line));*/
while ((line = reader.readLine()) != null) {
sb.append(line);
// Log.d("sb.append(line)--------------------------->",""+sb.append(line));
// Log.d("Line--------------------------->",""+line);
}
Log.d("sb.toSting-------------------->",""+sb.toString());
while ((b = cis.read(d)) != -1) {
//Log.d("cis.read(d)------------------------>>>>>>>",""+cis.read(d));
fos.write(d, 0, b);
}
fos.flush();
fos.close();
cis.close();
}
I am working on some big files and when I will go for the full file encryption/decryption. It is taking too much of time. Now I want to encrypt only first 1024 bytes of file and the rest of the bytes will remain the same.
Here is my code:
static void encrypt(String inputPath, String outputPath) throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException
{
// Here you read the cleartext.
FileInputStream fis = new FileInputStream(inputPath);
// This stream write the encrypted text. This stream will be wrapped by another stream.
FileOutputStream fos = new FileOutputStream(outputPath);
// Length is 16 byte
SecretKeySpec sks = new SecretKeySpec("MyDifficultPassw".getBytes(), "AES");
// Create cipher
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, sks);
// Wrap the output stream
CipherOutputStream cos = new CipherOutputStream(fos, cipher);
// Write bytes
int b;
int count = 0;
byte[] d = new byte[1024];
while((b = fis.read(d)) != -1) {
if(count <= 1024){
count += b;
cos.write(d, 0, b);
}else{
cos.write(d, 0, b);
}
// cos.write(d, 0, b);
}
// Flush and close streams.
cos.flush();
cos.close();
fis.close();
}
static byte[] decrypt(String inputPath) throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
FileInputStream fis = new FileInputStream(inputPath);
// FileOutputStream fos = new FileOutputStream(outputPath);
SecretKeySpec sks = new SecretKeySpec("MyDifficultPassw".getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, sks);
CipherInputStream cis = new CipherInputStream(fis, cipher);
int b;
byte[] d = new byte[1024];
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int count =0;
while((b = cis.read(d)) != -1) {
if(count <= 1024){
count += b;
bos.write(d, 0, b);
}else{
bos.write(d, 0, b);
}
}
byte[] completeBytes = bos.toByteArray();
cis.close();
return completeBytes;
}
Please suggest something..
load the first 1024 bytes from the file, encrypt them then write them back. convert this C# code to java for reading the first 1024 bytes:
byte[] chunkData = new byte[];
int chunkSize = 1024;
using(FileStream fsInput = FileStream(PATH TO FileMode.Read)
fsInput.Read(chunkData, 0, chunkSize);