hi guys is there any simple way to encrypt and decrypt the images across platforms like decrypting the image in android encrypted in the iPhone and vise-versa.
Thanks in Advance..
You can use 56 bit DES encryption. It is supported both in iphone and android. You cannot use RSA because image may be larger than 127 byte. Two years before when I was trying with AES 128 bit encryption. I found there was limitation of using AES 128 bit encryption and put it in market place. So avoid AES also. java supprots AES. Hence nadorid also supports DES
AES encryption is the best way encrypt a file in android or in IOS.In android I have tried encryption.This link will help you to do in android .The below code will help tou to encrypt a byte array with the key in android.
encryptionKey will be your password
public static byte[] encrypt(byte[] key, byte[] data) throws Exception
{
SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(data);
return encrypted;
}
/**
* DEcrypt byte array with given Key using AES Algorithm
* Key can be generated using <Code>getKey()</Code>
* #param key Key that Is used for decrypting data
* #param data Data passed to decrypt
* #return decrypted data
* */
public static byte[] decrypt1(byte[] key, byte[] encrypted) throws Exception
{
SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] decrypted = cipher.doFinal(encrypted);
return decrypted;
}
/**
* get the Key for encryption this can be used for while decrypting and encrypting too.
* */
public static byte[] getKey() throws Exception
{
byte[] keyStart = EncrypteDecrypte.encryptionKey.getBytes();
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(keyStart);
kgen.init(128, sr); // 192 and 256 bits may not be available
SecretKey skey = kgen.generateKey();
byte[] key = skey.getEncoded();
return key;
}
Related
I just want AES/CBC 128 bit encryption decryption in openSSl c and Android with identical result.
I have to send encrypted data using pre defined 16 bytes key from android to c via bluetooth.
So is there any common mechanism which i can use in both to produce identical result of encryption and decryption.
Any help would be appreciate.
Thank you.
I found a solution which work perfectly for Android.
I am going to post the answer if it would help anyone.
static String IV = "AAAAAAAAAAAAAAAA";
static String encryptionKey = "0123456789ABCDEF";
public static String decrypt(byte[] cipherText, String encryptionKey) throws Exception{
Cipher cipher = Cipher.getInstance("AES/CBC/ZeroBytePadding"/*, "SunJCE"*/);
SecretKeySpec key = new SecretKeySpec(encryptionKey.getBytes("UTF-8"), "AES");
cipher.init(Cipher.DECRYPT_MODE, key,new IvParameterSpec(IV.getBytes("UTF-8")));
return new String(cipher.doFinal(cipherText),"UTF-8");
}
public static byte[] encrypt(String plainText, String encryptionKey) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/ZeroBytePadding"/*, "SunJCE"*/);
SecretKeySpec key = new SecretKeySpec(encryptionKey.getBytes("UTF-8"), "AES");
cipher.init(Cipher.ENCRYPT_MODE, key,new IvParameterSpec(IV.getBytes("UTF-8")));
return cipher.doFinal(plainText.getBytes("UTF-8"));
}
//To Encrypt
byte[] cipher = encrypt(plaintext, encryptionKey);
System.out.print("cipher: ");
//To Decrypt
String decrypted = decrypt(cipher, encryptionKey);
System.out.println("decrypt: " + decrypted);
I am using the following code to encrypt a file in sd card.
void encrypt() throws IOException, NoSuchAlgorithmException, NoSuchPaddingException,
InvalidKeyException {
String myString = getOutputFile();
File myFile = new File(myString);
FileInputStream inputStream = new FileInputStream(myFile);
File encodedfile = new File(path,"filename" + ".mp4");
FileOutputStream outputStream = new FileOutputStream(encodedfile);
SecretKeySpec sks = new SecretKeySpec("MyDifficultPassw".getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, sks);
CipherOutputStream cos = new CipherOutputStream(outputStream, 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();
As i am new to cryptography, i don't know whether am using 256 bit encryption. Am i using a 256 bit encryption. If not what code should i add to make it a 256 bit encryption
No, you are using 128 bit encryption, as your password is 16 ASCII characters. Combine that with the default character set of Android (UTF-8) and the result of getBytes() will be key data of 16 bytes, or 128 bits.
Not that it matters if it is 128 bit or 256 bit. If you directly store the password or key in your code, use a password as key or if you rely on the default ECB mode of encryption, then your code is not secure.
Learn about key management, use at least CBC mode encryption and create a fully random AES key of 256 bits (32 bytes). The AES keysize (as used within Cipher) fully depends on the key in Java / Android.
I have an Android app that encrypts data using AES with ECB and ZeroBytePadding. Everything works fine in that environment: encrypted data gets decrypted in Android without a problem, as follows:
public static String encrypt(byte[] raw, byte[] clear) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/ZeroBytePadding");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(clear);
return android.util.Base64.encodeToString(encrypted, android.util.Base64.NO_WRAP);
}
public static byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/ZeroBytePadding");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] decrypted = cipher.doFinal(encrypted);
return decrypted;
}
However, I recently decided to decrypt the data in a Web app and when I tried to use the same decrypt() method, Cipher.getInstance("AES/ECB/ZeroBytePadding") threw an exception:
java.security.NoSuchAlgorithmException: Cannot find any provider supporting
AES/ECB/ZeroBytePadding
I assume that some Android library is providing a suitable cipher provider that is missing from javax.crypto.Cipher. Has anyone else had this problem or know what I can do about it? Changing the cipher padding to PKCS5PADDING is not an option, due to the many messages that are already encrypted with the earlier options.
Actually there is really not such an algorithm. Look at official java docs here http://docs.oracle.com/javase/7/docs/api/javax/crypto/Cipher.html
I have developed a main app, now I need to develop a second app which is identical to the first but only perform 70% of the functionality. I have modularized the main app's functionality but now I want to be able to turn them on/off base on a configuration file. The values in this configuration file need to be accessible within the context of Activities and Services. A lot of people suggested using SharedPrefences, but I don't need end user to modify this. It's only meant for developer to configure these settings. What's the best approach for this?
Now in android data can be stored in these ways
Now you don’t want to store configuration in shared preference, So i would suggest you to go in 2 ways
Create a SQLite database that is accessible by both apps OR
Create a file that stores the configuration data and is accessible by both apps
Whatever the method that you choose to store the data encrypt it using some encryption algorithm like this
private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(clear);
return encrypted;
}
private static byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] decrypted = cipher.doFinal(encrypted);
return decrypted;
}
And invoke them like this:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.PNG, 100, baos); // bm is the bitmap object
byte[] b = baos.toByteArray();
byte[] keyStart = "this is a key".getBytes();
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(keyStart);
kgen.init(128, sr); // 192 and 256 bits may not be available
SecretKey skey = kgen.generateKey();
byte[] key = skey.getEncoded();
// encrypt
byte[] encryptedData = encrypt(key,b);
// decrypt
byte[] decryptedData = decrypt(key,encryptedData);
Now you can use the key to access these values and user would not be able to understand you configuration information
or you can use a web service to save data onto the server and your both apps can use that web service to get the configuration, It wont work offline though :(
I want to encrypt/decrypt some passwords in the SQLite database of my application. To do that I have searched on the internet and I have found the AES algorithm.
I have this code:
public String encript(String dataToEncrypt)
throws NoSuchAlgorithmException, NoSuchPaddingException,
InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
// I'm using AES encription
if(!dataToEncrypt.equals("")){
String key = "FMVWf8d_sm#fz";
Cipher c = Cipher.getInstance("AES");
SecretKeySpec k;
try {
k = new SecretKeySpec(key.getBytes(), "AES");
c.init(Cipher.ENCRYPT_MODE, k);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return new String(c.doFinal(Base64.decode(dataToEncrypt)));
}
return "";
}
public String decript(String encryptedData)
throws NoSuchAlgorithmException, NoSuchPaddingException,
InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
if(!encryptedData.equals("")){
String key = "FMVWf8d_sm#fz";
Cipher c = Cipher.getInstance("AES");
SecretKeySpec k = new SecretKeySpec(Base64.decode(key), "AES");
c.init(Cipher.DECRYPT_MODE, k);
return new String(c.doFinal(Base64.decode(encryptedData)));
}
return "";
}
After running this I get this error on encrypt method:
01-27 14:50:51.698: ERROR/ACTIVITY(782):
java.security.InvalidKeyException: Key length not 128/192/256 bits.
I have seen some other cases here on stackoverflow but I want to give the key to the AES not to generate it...
Can somebody help me with this? If there is other encryption method to use but without using another jars or external classes and to let me give the key.
Thank you very much!
The error message makes it perfectly clear: your encryption key must be of certain size: 128, 192 or 256 bits. And your key is 104 bits. Note, that as you want to use only printable characters in your key, the length of the key should be 192 or longer bits, cause your alphabet (set of characters that you use) makes encryption weaker.
Usual practice is such:
Get password (in your case String key = "FMVWf8d_sm#fz";)
Generate using some hash function key with length 128, 192 or 256
Put it into encryption algorithm
Have fun
So you are missing key generation stage. Do smth like:
// Get the KeyGenerator
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128); // 192 and 256 bits may not be available
// Generate the secret key specs.
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
// Instantiate the cipher
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted =
cipher.doFinal((args.length == 0 ?
"This is just an example" : args[0]).getBytes());
System.out.println("encrypted string: " + asHex(encrypted));
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] original =
cipher.doFinal(encrypted);
String originalString = new String(original);
System.out.println("Original string: " +
originalString + " " + asHex(original));