30

My question is how to encrypt a String:

String AndroidId;

@Override
public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.download_movie_activity);

  cancel = (Button)findViewById(R.id.img_cancle);

  linear= (LinearLayout)findViewById(R.id.progress);
  linear.setVisibility(View.GONE);

  String encrypted = "MzIyNTE2" + "OTQNzM4NTQ=";

  Log.e("Encrypt", encrypted);

  WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
  WifiInfo wInfo = wifiManager.getConnectionInfo();
  AndroidId = wInfo.getMacAddress();

  AndroidId=encrypted;

How do i encrypt my AndroidId in which I storing a MAC address.

Sumit Kumar
  • 643
  • 1
  • 8
  • 19
  • try this http://www.code2learn.com/2011/06/encryption-and-decryption-of-data-using.html – D.J Oct 19 '16 at 06:00
  • For encryption and decryption [see this link](http://stackoverflow.com/a/5220925/5689844) – Emdad Hossain Oct 19 '16 at 06:01
  • Use AES or Chacha20 Encryption http://stackoverflow.com/questions/6788018/android-encryption-decryption-with-aes – Zar E Ahmer Oct 19 '16 at 06:02
  • I think answer is already given at http://stackoverflow.com/questions/5220761/fast-and-simple-string-encrypt-decrypt-in-java this link. please check it – Ronit kadwane Oct 19 '16 at 06:04
  • Use [this](https://github.com/ryan652/EasyCrypt) library. – priyank Aug 04 '17 at 23:35
  • **Warning** at the time of writing none of the answers is anywhere near secure. **Do not use copy / paste security**, because it doesn't exist. Any answer that uses `SecureRandom` to derive a key from a password is **broken** and may lead to data loss. Do not use ECB mode because it may directly leak information about the plaintext input (string). – Maarten Bodewes Feb 24 '20 at 11:58
  • I've protected this question not because of above, but because of the many code only answers, that don't even specify **how** a string is protected. Please do indicate how the code is to be used and what protection it offers. And given the various answers, how you are supposed to get the correct string back without encoding errors. – Maarten Bodewes Feb 24 '20 at 12:04

5 Answers5

52

You can use Cipher for this.

This class provides the functionality of a cryptographic cipher for encryption and decryption. It forms the core of the Java Cryptographic Extension (JCE) framework.

Sample of encryption and decryption:

public static SecretKey generateKey() 
    throws NoSuchAlgorithmException, InvalidKeySpecException 
{ 
    return secret = new SecretKeySpec(password.getBytes(), "AES"); 
}

public static byte[] encryptMsg(String message, SecretKey secret)
    throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidParameterSpecException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException 
{ 
   /* Encrypt the message. */
   Cipher cipher = null; 
   cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
   cipher.init(Cipher.ENCRYPT_MODE, secret); 
   byte[] cipherText = cipher.doFinal(message.getBytes("UTF-8")); 
   return cipherText; 
}

public static String decryptMsg(byte[] cipherText, SecretKey secret) 
    throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidParameterSpecException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException 
{
    /* Decrypt the message, given derived encContentValues and initialization vector. */
    Cipher cipher = null;
    cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
    cipher.init(Cipher.DECRYPT_MODE, secret); 
    String decryptString = new String(cipher.doFinal(cipherText), "UTF-8");
    return decryptString; 
}

To encrypt:

SecretKey secret = generateKey();
EncUtil.encryptMsg(String toEncrypt, secret))

To decrypt:

EncUtil.decryptMsg(byte[] toDecrypt, secret))
Steve Blackwell
  • 5,904
  • 32
  • 49
Patrick R
  • 6,621
  • 1
  • 24
  • 27
18

Using these helper class you can encrypt and decrypt string in android simple way, but this will work only for below Android 7.0, for Android 8.0 and above you can find from here

import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

public class AESHelper {

public static String encrypt(String seed, String cleartext) throws Exception {
    byte[] rawKey = getRawKey(seed.getBytes());
    byte[] result = encrypt(rawKey, cleartext.getBytes());
    return toHex(result);
}

public static String decrypt(String seed, String encrypted) throws Exception {
    byte[] rawKey = getRawKey(seed.getBytes());
    byte[] enc = toByte(encrypted);
    byte[] result = decrypt(rawKey, enc);
    return new String(result);
}

private static byte[] getRawKey(byte[] seed) throws Exception {
    KeyGenerator kgen = KeyGenerator.getInstance("AES");
    SecureRandom sr = SecureRandom.getInstance("SHA1PRNG","Crypto");
    sr.setSeed(seed);
    kgen.init(128, sr); // 192 and 256 bits may not be available
    SecretKey skey = kgen.generateKey();
    byte[] raw = skey.getEncoded();
    return raw;
}


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;
}

public static String toHex(String txt) {
    return toHex(txt.getBytes());
}
public static String fromHex(String hex) {
    return new String(toByte(hex));
}

public static byte[] toByte(String hexString) {
    int len = hexString.length()/2;
    byte[] result = new byte[len];
    for (int i = 0; i < len; i++)
        result[i] = Integer.valueOf(hexString.substring(2*i, 2*i+2), 16).byteValue();
    return result;
}

public static String toHex(byte[] buf) {
    if (buf == null)
        return "";
    StringBuffer result = new StringBuffer(2*buf.length);
    for (int i = 0; i < buf.length; i++) {
        appendHex(result, buf[i]);
    }
    return result.toString();
}
private final static String HEX = "0123456789ABCDEF";
private static void appendHex(StringBuffer sb, byte b) {
    sb.append(HEX.charAt((b>>4)&0x0f)).append(HEX.charAt(b&0x0f));
}
}

below is your method for encryption and decryption for string,

public String encryption(String strNormalText){
    String seedValue = "YourSecKey";
    String normalTextEnc="";
    try {
        normalTextEnc = AESHelper.encrypt(seedValue, strNormalText);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return normalTextEnc;
}
public String decryption(String strEncryptedText){
    String seedValue = "YourSecKey";
    String strDecryptedText="";
    try {
        strDecryptedText = AESHelper.decrypt(seedValue, strEncryptedText);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return strDecryptedText;
}

finally you can use like as:

String encryptedString = encryption("Input Normal String");
String decryptedString = decryption("Input Encrypted String");
varotariya vajsi
  • 3,965
  • 37
  • 39
  • thnx bro !!! i done it months ago !! but thnx for the comment , and also i knew now that's the way to do it. :) – Sumit Kumar Feb 10 '17 at 07:10
  • 3
    java.security.NoSuchProviderException: no such provider: Crypto – Web.11 Apr 21 '17 at 00:24
  • https://android-developers.googleblog.com/2016/06/security-crypto-provider-deprecated-in.html – Duna Jul 21 '17 at 09:01
  • 5
    Why reinvent the wheel? Use a [library](https://github.com/ryan652/EasyCrypt) to avoid implementation vulnerabilities. – priyank Aug 04 '17 at 23:39
  • Hii @varotariyavajsi this is deprecated from android N onward, ********** PLEASE READ ************ * * New versions of the Android SDK no longer support the Crypto provider. * If your app was relying on setSeed() to derive keys from strings, you * should switch to using SecretKeySpec to load raw key bytes directly OR * use a real key derivation function (KDF). See advice here : * http://android-developers.blogspot.com/2016/06/security-crypto-provider-deprecated-in.html *********************************** – PankajAndroid Jan 12 '18 at 08:35
  • This code is insecure and should not be used. For instance, the use of the raw AES ECB cipher for encryption. – Isaac Potoczny-Jones Feb 23 '18 at 21:01
8

Actually Saravanan Ee's answer is the correct one. But there are several logic and syntax errors. Here is a correct code snippet of his approach.

private String SECRET_KEY = "aesEncryptionKey";
private String INIT_VECTOR = "encryptionIntVec";

public static String encrypt(String value) {
    try {
        IvParameterSpec iv = new IvParameterSpec(INIT_VECTOR.getBytes("UTF-8"));
        SecretKeySpec skeySpec = new SecretKeySpec(SECRET_KEY.getBytes("UTF-8"), "AES");
     
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
     
        byte[] encrypted = cipher.doFinal(value.getBytes());
        return Base64.encodeToString(encrypted, Base64.DEFAULT);
    } catch (Exception ex) {
        ex.printStackTrace();
    }
    return null;
}

public static String decrypt(String value) {
    try {
        IvParameterSpec iv = new IvParameterSpec(INIT_VECTOR.getBytes("UTF-8"));
        SecretKeySpec skeySpec = new SecretKeySpec(SECRET_KEY.getBytes("UTF-8"), "AES");
     
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
        cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
        byte[] original = cipher.doFinal(Base64.decode(value, Base64.DEFAULT));
     
        return new String(original);
    } catch (Exception ex) {
        ex.printStackTrace();
    }
     
    return null;
}

USAGE:

Encryption:

String textForEncryption = "This my text that will be encrypted!";
String encryptedString;
encryptedString = encrypt(textForEncryption);
//Result: BItjtWPNKXjdHZ6clbtXWAzUwJAbMpIaP294eRB9+7BR0g+gJ9jZv4AZt+8epG36

Decryption:

String encryptedText = "BItjtWPNKXjdHZ6clbtXWAzUwJAbMpIaP294eRB9+7BR0g+gJ9jZv4AZt+8epG36";
String decryptedString;
decryptedString = decrypt(encryptedText);
//Result: This my text that will be encrypted!
Ruzin
  • 1,645
  • 2
  • 14
  • 14
  • Kindly note that the usage of a **static IV** is **UNSECURE** and makes the complete encryption vulnerable. It is better to generate a random IV for each encryption, pass it along with the ciphertext and use it for decryption. – Michael Fehr Oct 09 '21 at 15:21
  • You are right, but the code snippet is taken from a project with concrete request that the IV and SECRET KEY are both static and immutable. :) – Ruzin Oct 09 '21 at 19:05
  • Note that constants SECRET_KEY and INIT_VECTOR should be declared as static, to have a full working code :). – akelec Mar 07 '22 at 15:44
3

Using BlueFish algorithm you can simple encrypt & decrypt any string. Blowfish with key size of 128-bit up to 448-bit, its considered as a better faster algorithm. Try as follows

public class CryptUtil {
private static final String ALGORITHM = "Blowfish";
private static final String MODE = "Blowfish/CBC/PKCS5Padding";
private static final String IV = "abcdefgh";
private static final String KEY= "MyKey";

public static  String encrypt(String value ) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
    SecretKeySpec secretKeySpec = new SecretKeySpec(KEY.getBytes(), ALGORITHM);
    Cipher cipher = Cipher.getInstance(MODE);
    cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, new IvParameterSpec(IV.getBytes()));
    byte[] values = cipher.doFinal(value.getBytes());
    return Base64.encodeToString(values, Base64.DEFAULT);
}

public static  String decrypt(String value) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
    byte[] values = Base64.decode(value, Base64.DEFAULT);
    SecretKeySpec secretKeySpec = new SecretKeySpec(KEY.getBytes(), ALGORITHM);
    Cipher cipher = Cipher.getInstance(MODE);
    cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, new IvParameterSpec(IV.getBytes()));
    return new String(cipher.doFinal(values));
  }

}
Farid Haq
  • 3,728
  • 1
  • 21
  • 15
  • 2
    Not even Bruce Schneier - i.e. the author - recommends Blowfish anymore: "NOTE: Blowfish was created in **1993**. While there is still no practical attack against the cipher, it only has a 64-bit block length and was optimized for 32-bit CPUs. If you are thinking of using this algorithm, I recommend that you use Twofish instead." A string is not a key. `getBytes` without character encoding is dangerous. Reusing an IV is dangerous. – Maarten Bodewes Feb 24 '20 at 12:01
0
public static String encrypt(String value) {
    String key = "aesEncryptionKey";
    String initVector = "encryptionIntVec";
    try {
        IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
        SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);

        byte[] encrypted = cipher.doFinal(value.getBytes());
        return Base64.encode(encrypted);
    } catch (Exception ex) {
        ex.printStackTrace();
    }
    return null;
}
public static String decrypt(String value) {
    String key = "aesEncryptionKey";
    String initVector = "encryptionIntVec";
    try {
        IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
        SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
        cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
        byte[] original = cipher.doFinal(Base64.decode(value));

        return new String(original);
    } catch (Exception ex) {
        ex.printStackTrace();
    }

    return null;
}