47

I need fast and simple way to encrypt/decrypt a "lot" of String data. I tried jasypt but it crashes on my Android phone. I have about 2000 records (strings).

BasicTextEncryptor textEncryptor = new BasicTextEncryptor();
textEncryptor.setPassword("password");
String myEncryptedText = textEncryptor.encrypt(input);

Is there some other way? I don't need extremely high security, it needs to be fast!

svenkapudija
  • 5,128
  • 14
  • 68
  • 96
  • 1
    possible duplicate of [Java - encrypt / decrypt user name and password from a configuration file](http://stackoverflow.com/questions/339004/java-encrypt-decrypt-user-name-and-password-from-a-configuration-file) – dimo414 Jun 09 '14 at 03:20
  • @dimo414: I legitimately do not see that as a duplicate to this question. Android is a subset of Java, but there are a decent amount of libraries that *aren't* usable in Android. – Makoto Jun 09 '14 at 04:41
  • @Makoto: a reasonable objection, but the accepted answer is literally just copied code from another answer (and, interestingly, isn't the accepted answer there). Further, I don't see anything in the answers that seems Android-specific. – dimo414 Jun 09 '14 at 04:57
  • Im using jasypt with android and everythings seems ok. Can you share why it crashes on your phone ? – AsafK Nov 05 '14 at 22:13

4 Answers4

63

Update

the library already have Java/Kotlin support, see github.


Original

To simplify I did a class to be used simply, I added it on Encryption library to use it you just do as follow:

Add the gradle library:

compile 'se.simbio.encryption:library:2.0.0'

and use it:

Encryption encryption = Encryption.getDefault("Key", "Salt", new byte[16]);
String encrypted = encryption.encryptOrNull("top secret string");
String decrypted = encryption.decryptOrNull(encrypted);

if you not want add the Encryption library you can just copy the following class to your project. If you are in an android project you need to import android Base64 in this class, if you are in a pure java project you need to add this class manually you can get it here

Encryption.java

package se.simbio.encryption;

import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;

/**
 * A class to make more easy and simple the encrypt routines, this is the core of Encryption library
 */
public class Encryption {

    /**
     * The Builder used to create the Encryption instance and that contains the information about
     * encryption specifications, this instance need to be private and careful managed
     */
    private final Builder mBuilder;

    /**
     * The private and unique constructor, you should use the Encryption.Builder to build your own
     * instance or get the default proving just the sensible information about encryption
     */
    private Encryption(Builder builder) {
        mBuilder = builder;
    }

    /**
     * @return an default encryption instance or {@code null} if occur some Exception, you can
     * create yur own Encryption instance using the Encryption.Builder
     */
    public static Encryption getDefault(String key, String salt, byte[] iv) {
        try {
            return Builder.getDefaultBuilder(key, salt, iv).build();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * Encrypt a String
     *
     * @param data the String to be encrypted
     *
     * @return the encrypted String or {@code null} if you send the data as {@code null}
     *
     * @throws UnsupportedEncodingException       if the Builder charset name is not supported or if
     *                                            the Builder charset name is not supported
     * @throws NoSuchAlgorithmException           if the Builder digest algorithm is not available
     *                                            or if this has no installed provider that can
     *                                            provide the requested by the Builder secret key
     *                                            type or it is {@code null}, empty or in an invalid
     *                                            format
     * @throws NoSuchPaddingException             if no installed provider can provide the padding
     *                                            scheme in the Builder digest algorithm
     * @throws InvalidAlgorithmParameterException if the specified parameters are inappropriate for
     *                                            the cipher
     * @throws InvalidKeyException                if the specified key can not be used to initialize
     *                                            the cipher instance
     * @throws InvalidKeySpecException            if the specified key specification cannot be used
     *                                            to generate a secret key
     * @throws BadPaddingException                if the padding of the data does not match the
     *                                            padding scheme
     * @throws IllegalBlockSizeException          if the size of the resulting bytes is not a
     *                                            multiple of the cipher block size
     * @throws NullPointerException               if the Builder digest algorithm is {@code null} or
     *                                            if the specified Builder secret key type is
     *                                            {@code null}
     * @throws IllegalStateException              if the cipher instance is not initialized for
     *                                            encryption or decryption
     */
    public String encrypt(String data) throws UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, InvalidKeyException, InvalidKeySpecException, BadPaddingException, IllegalBlockSizeException {
        if (data == null) return null;
        SecretKey secretKey = getSecretKey(hashTheKey(mBuilder.getKey()));
        byte[] dataBytes = data.getBytes(mBuilder.getCharsetName());
        Cipher cipher = Cipher.getInstance(mBuilder.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, mBuilder.getIvParameterSpec(), mBuilder.getSecureRandom());
        return Base64.encodeToString(cipher.doFinal(dataBytes), mBuilder.getBase64Mode());
    }

    /**
     * This is a sugar method that calls encrypt method and catch the exceptions returning
     * {@code null} when it occurs and logging the error
     *
     * @param data the String to be encrypted
     *
     * @return the encrypted String or {@code null} if you send the data as {@code null}
     */
    public String encryptOrNull(String data) {
        try {
            return encrypt(data);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * This is a sugar method that calls encrypt method in background, it is a good idea to use this
     * one instead the default method because encryption can take several time and with this method
     * the process occurs in a AsyncTask, other advantage is the Callback with separated methods,
     * one for success and other for the exception
     *
     * @param data     the String to be encrypted
     * @param callback the Callback to handle the results
     */
    public void encryptAsync(final String data, final Callback callback) {
        if (callback == null) return;
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    String encrypt = encrypt(data);
                    if (encrypt == null) {
                        callback.onError(new Exception("Encrypt return null, it normally occurs when you send a null data"));
                    }
                    callback.onSuccess(encrypt);
                } catch (Exception e) {
                    callback.onError(e);
                }
            }
        }).start();
    }

    /**
     * Decrypt a String
     *
     * @param data the String to be decrypted
     *
     * @return the decrypted String or {@code null} if you send the data as {@code null}
     *
     * @throws UnsupportedEncodingException       if the Builder charset name is not supported or if
     *                                            the Builder charset name is not supported
     * @throws NoSuchAlgorithmException           if the Builder digest algorithm is not available
     *                                            or if this has no installed provider that can
     *                                            provide the requested by the Builder secret key
     *                                            type or it is {@code null}, empty or in an invalid
     *                                            format
     * @throws NoSuchPaddingException             if no installed provider can provide the padding
     *                                            scheme in the Builder digest algorithm
     * @throws InvalidAlgorithmParameterException if the specified parameters are inappropriate for
     *                                            the cipher
     * @throws InvalidKeyException                if the specified key can not be used to initialize
     *                                            the cipher instance
     * @throws InvalidKeySpecException            if the specified key specification cannot be used
     *                                            to generate a secret key
     * @throws BadPaddingException                if the padding of the data does not match the
     *                                            padding scheme
     * @throws IllegalBlockSizeException          if the size of the resulting bytes is not a
     *                                            multiple of the cipher block size
     * @throws NullPointerException               if the Builder digest algorithm is {@code null} or
     *                                            if the specified Builder secret key type is
     *                                            {@code null}
     * @throws IllegalStateException              if the cipher instance is not initialized for
     *                                            encryption or decryption
     */
    public String decrypt(String data) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
        if (data == null) return null;
        byte[] dataBytes = Base64.decode(data, mBuilder.getBase64Mode());
        SecretKey secretKey = getSecretKey(hashTheKey(mBuilder.getKey()));
        Cipher cipher = Cipher.getInstance(mBuilder.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, secretKey, mBuilder.getIvParameterSpec(), mBuilder.getSecureRandom());
        byte[] dataBytesDecrypted = (cipher.doFinal(dataBytes));
        return new String(dataBytesDecrypted);
    }

    /**
     * This is a sugar method that calls decrypt method and catch the exceptions returning
     * {@code null} when it occurs and logging the error
     *
     * @param data the String to be decrypted
     *
     * @return the decrypted String or {@code null} if you send the data as {@code null}
     */
    public String decryptOrNull(String data) {
        try {
            return decrypt(data);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * This is a sugar method that calls decrypt method in background, it is a good idea to use this
     * one instead the default method because decryption can take several time and with this method
     * the process occurs in a AsyncTask, other advantage is the Callback with separated methods,
     * one for success and other for the exception
     *
     * @param data     the String to be decrypted
     * @param callback the Callback to handle the results
     */
    public void decryptAsync(final String data, final Callback callback) {
        if (callback == null) return;
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    String decrypt = decrypt(data);
                    if (decrypt == null) {
                        callback.onError(new Exception("Decrypt return null, it normally occurs when you send a null data"));
                    }
                    callback.onSuccess(decrypt);
                } catch (Exception e) {
                    callback.onError(e);
                }
            }
        }).start();
    }

    /**
     * creates a 128bit salted aes key
     *
     * @param key encoded input key
     *
     * @return aes 128 bit salted key
     *
     * @throws NoSuchAlgorithmException     if no installed provider that can provide the requested
     *                                      by the Builder secret key type
     * @throws UnsupportedEncodingException if the Builder charset name is not supported
     * @throws InvalidKeySpecException      if the specified key specification cannot be used to
     *                                      generate a secret key
     * @throws NullPointerException         if the specified Builder secret key type is {@code null}
     */
    private SecretKey getSecretKey(char[] key) throws NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeySpecException {
        SecretKeyFactory factory = SecretKeyFactory.getInstance(mBuilder.getSecretKeyType());
        KeySpec spec = new PBEKeySpec(key, mBuilder.getSalt().getBytes(mBuilder.getCharsetName()), mBuilder.getIterationCount(), mBuilder.getKeyLength());
        SecretKey tmp = factory.generateSecret(spec);
        return new SecretKeySpec(tmp.getEncoded(), mBuilder.getKeyAlgorithm());
    }

    /**
     * takes in a simple string and performs an sha1 hash
     * that is 128 bits long...we then base64 encode it
     * and return the char array
     *
     * @param key simple inputted string
     *
     * @return sha1 base64 encoded representation
     *
     * @throws UnsupportedEncodingException if the Builder charset name is not supported
     * @throws NoSuchAlgorithmException     if the Builder digest algorithm is not available
     * @throws NullPointerException         if the Builder digest algorithm is {@code null}
     */
    private char[] hashTheKey(String key) throws UnsupportedEncodingException, NoSuchAlgorithmException {
        MessageDigest messageDigest = MessageDigest.getInstance(mBuilder.getDigestAlgorithm());
        messageDigest.update(key.getBytes(mBuilder.getCharsetName()));
        return Base64.encodeToString(messageDigest.digest(), Base64.NO_PADDING).toCharArray();
    }

    /**
     * When you encrypt or decrypt in callback mode you get noticed of result using this interface
     */
    public interface Callback {

        /**
         * Called when encrypt or decrypt job ends and the process was a success
         *
         * @param result the encrypted or decrypted String
         */
        void onSuccess(String result);

        /**
         * Called when encrypt or decrypt job ends and has occurred an error in the process
         *
         * @param exception the Exception related to the error
         */
        void onError(Exception exception);

    }

    /**
     * This class is used to create an Encryption instance, you should provide ALL data or start
     * with the Default Builder provided by the getDefaultBuilder method
     */
    public static class Builder {

        private byte[] mIv;
        private int mKeyLength;
        private int mBase64Mode;
        private int mIterationCount;
        private String mSalt;
        private String mKey;
        private String mAlgorithm;
        private String mKeyAlgorithm;
        private String mCharsetName;
        private String mSecretKeyType;
        private String mDigestAlgorithm;
        private String mSecureRandomAlgorithm;
        private SecureRandom mSecureRandom;
        private IvParameterSpec mIvParameterSpec;

        /**
         * @return an default builder with the follow defaults:
         * the default char set is UTF-8
         * the default base mode is Base64
         * the Secret Key Type is the PBKDF2WithHmacSHA1
         * the default salt is "some_salt" but can be anything
         * the default length of key is 128
         * the default iteration count is 65536
         * the default algorithm is AES in CBC mode and PKCS 5 Padding
         * the default secure random algorithm is SHA1PRNG
         * the default message digest algorithm SHA1
         */
        public static Builder getDefaultBuilder(String key, String salt, byte[] iv) {
            return new Builder()
                    .setIv(iv)
                    .setKey(key)
                    .setSalt(salt)
                    .setKeyLength(128)
                    .setKeyAlgorithm("AES")
                    .setCharsetName("UTF8")
                    .setIterationCount(1)
                    .setDigestAlgorithm("SHA1")
                    .setBase64Mode(Base64.DEFAULT)
                    .setAlgorithm("AES/CBC/PKCS5Padding")
                    .setSecureRandomAlgorithm("SHA1PRNG")
                    .setSecretKeyType("PBKDF2WithHmacSHA1");
        }

        /**
         * Build the Encryption with the provided information
         *
         * @return a new Encryption instance with provided information
         *
         * @throws NoSuchAlgorithmException if the specified SecureRandomAlgorithm is not available
         * @throws NullPointerException     if the SecureRandomAlgorithm is {@code null} or if the
         *                                  IV byte array is null
         */
        public Encryption build() throws NoSuchAlgorithmException {
            setSecureRandom(SecureRandom.getInstance(getSecureRandomAlgorithm()));
            setIvParameterSpec(new IvParameterSpec(getIv()));
            return new Encryption(this);
        }

        /**
         * @return the charset name
         */
        private String getCharsetName() {
            return mCharsetName;
        }

        /**
         * @param charsetName the new charset name
         *
         * @return this instance to follow the Builder patter
         */
        public Builder setCharsetName(String charsetName) {
            mCharsetName = charsetName;
            return this;
        }

        /**
         * @return the algorithm
         */
        private String getAlgorithm() {
            return mAlgorithm;
        }

        /**
         * @param algorithm the algorithm to be used
         *
         * @return this instance to follow the Builder patter
         */
        public Builder setAlgorithm(String algorithm) {
            mAlgorithm = algorithm;
            return this;
        }

        /**
         * @return the key algorithm
         */
        private String getKeyAlgorithm() {
            return mKeyAlgorithm;
        }

        /**
         * @param keyAlgorithm the keyAlgorithm to be used in keys
         *
         * @return this instance to follow the Builder patter
         */
        public Builder setKeyAlgorithm(String keyAlgorithm) {
            mKeyAlgorithm = keyAlgorithm;
            return this;
        }

        /**
         * @return the Base 64 mode
         */
        private int getBase64Mode() {
            return mBase64Mode;
        }

        /**
         * @param base64Mode set the base 64 mode
         *
         * @return this instance to follow the Builder patter
         */
        public Builder setBase64Mode(int base64Mode) {
            mBase64Mode = base64Mode;
            return this;
        }

        /**
         * @return the type of aes key that will be created, on KITKAT+ the API has changed, if you
         * are getting problems please @see <a href="http://android-developers.blogspot.com.br/2013/12/changes-to-secretkeyfactory-api-in.html">http://android-developers.blogspot.com.br/2013/12/changes-to-secretkeyfactory-api-in.html</a>
         */
        private String getSecretKeyType() {
            return mSecretKeyType;
        }

        /**
         * @param secretKeyType the type of AES key that will be created, on KITKAT+ the API has
         *                      changed, if you are getting problems please @see <a href="http://android-developers.blogspot.com.br/2013/12/changes-to-secretkeyfactory-api-in.html">http://android-developers.blogspot.com.br/2013/12/changes-to-secretkeyfactory-api-in.html</a>
         *
         * @return this instance to follow the Builder patter
         */
        public Builder setSecretKeyType(String secretKeyType) {
            mSecretKeyType = secretKeyType;
            return this;
        }

        /**
         * @return the value used for salting
         */
        private String getSalt() {
            return mSalt;
        }

        /**
         * @param salt the value used for salting
         *
         * @return this instance to follow the Builder patter
         */
        public Builder setSalt(String salt) {
            mSalt = salt;
            return this;
        }

        /**
         * @return the key
         */
        private String getKey() {
            return mKey;
        }

        /**
         * @param key the key.
         *
         * @return this instance to follow the Builder patter
         */
        public Builder setKey(String key) {
            mKey = key;
            return this;
        }

        /**
         * @return the length of key
         */
        private int getKeyLength() {
            return mKeyLength;
        }

        /**
         * @param keyLength the length of key
         *
         * @return this instance to follow the Builder patter
         */
        public Builder setKeyLength(int keyLength) {
            mKeyLength = keyLength;
            return this;
        }

        /**
         * @return the number of times the password is hashed
         */
        private int getIterationCount() {
            return mIterationCount;
        }

        /**
         * @param iterationCount the number of times the password is hashed
         *
         * @return this instance to follow the Builder patter
         */
        public Builder setIterationCount(int iterationCount) {
            mIterationCount = iterationCount;
            return this;
        }

        /**
         * @return the algorithm used to generate the secure random
         */
        private String getSecureRandomAlgorithm() {
            return mSecureRandomAlgorithm;
        }

        /**
         * @param secureRandomAlgorithm the algorithm to generate the secure random
         *
         * @return this instance to follow the Builder patter
         */
        public Builder setSecureRandomAlgorithm(String secureRandomAlgorithm) {
            mSecureRandomAlgorithm = secureRandomAlgorithm;
            return this;
        }

        /**
         * @return the IvParameterSpec bytes array
         */
        private byte[] getIv() {
            return mIv;
        }

        /**
         * @param iv the byte array to create a new IvParameterSpec
         *
         * @return this instance to follow the Builder patter
         */
        public Builder setIv(byte[] iv) {
            mIv = iv;
            return this;
        }

        /**
         * @return the SecureRandom
         */
        private SecureRandom getSecureRandom() {
            return mSecureRandom;
        }

        /**
         * @param secureRandom the Secure Random
         *
         * @return this instance to follow the Builder patter
         */
        public Builder setSecureRandom(SecureRandom secureRandom) {
            mSecureRandom = secureRandom;
            return this;
        }

        /**
         * @return the IvParameterSpec
         */
        private IvParameterSpec getIvParameterSpec() {
            return mIvParameterSpec;
        }

        /**
         * @param ivParameterSpec the IvParameterSpec
         *
         * @return this instance to follow the Builder patter
         */
        public Builder setIvParameterSpec(IvParameterSpec ivParameterSpec) {
            mIvParameterSpec = ivParameterSpec;
            return this;
        }

        /**
         * @return the message digest algorithm
         */
        private String getDigestAlgorithm() {
            return mDigestAlgorithm;
        }

        /**
         * @param digestAlgorithm the algorithm to be used to get message digest instance
         *
         * @return this instance to follow the Builder patter
         */
        public Builder setDigestAlgorithm(String digestAlgorithm) {
            mDigestAlgorithm = digestAlgorithm;
            return this;
        }

    }

}    
Community
  • 1
  • 1
ademar111190
  • 14,215
  • 14
  • 85
  • 114
  • 1
    Works perfectly! Very easy to use! Thanks for updating such old post! – ButterBeast Jan 16 '14 at 16:57
  • This is nice, shame it's Android only ;-/ – Oliver Dixon May 04 '15 at 11:34
  • @iLoveUnicorns thanks :). In the future it will be for all java plataform, I'll remove the android dependence. – ademar111190 May 04 '15 at 13:44
  • ademar1111190 also have a look at my question. http://stackoverflow.com/questions/38007478/encrypt-and-decrypt-string-using-chacha20 – Zar E Ahmer Jun 24 '16 at 09:22
  • @rpattabi do you understand licenses? Can I change the project license to MIT? – ademar111190 Jul 27 '16 at 13:32
  • I am no expert either. If you want to allow anyone to use your lib without having to disclose their code, you can use MIT or Apache2.0 license. – rpattabi Jul 27 '16 at 14:21
  • @ademar111190 you may change your license to MIT or Apache if you want since it your code. However, if there were contributors to the project you have to talk with them to agree in the license change, since their contributions were GPL too. – saiyancoder Sep 26 '16 at 01:32
  • getDefault() used iteration count as 65536 and this is not fast. You should use iteration count to be 1 to make it fastest but least secure. – Aritra Roy Sep 26 '16 at 19:23
  • @JaiRajesh it is because the iteration count is "65536" you can use 1 and it will be faster – ademar111190 Oct 04 '16 at 18:07
  • @rpattabi I talked with other contributors and I changed the license to MIT thanks to saiyancoder for the tip – ademar111190 Oct 26 '16 at 13:49
  • @AritraRoy I changed the default to 1 like your tip, thank you – ademar111190 Oct 26 '16 at 13:49
  • @ademar111190 Thanks! – rpattabi Oct 26 '16 at 15:04
  • How to decrypt after restarting the app? I'm storing key, salt and iv in shared prefs but I get IllegalBlockSizeException when trying to decrypt after re-starting the app. It works fine when encrypting/decrypting in the same app instance. – IRPdevelop Mar 13 '18 at 03:06
  • Hi @IRPdevelop If you are using the same values it should work, don't matter if you have a different app instance. Can you share some code with me to me understand better what are you doing? You can create a ticket on GitHub repo. – ademar111190 Mar 13 '18 at 16:01
  • @ademar111190 my bad, it is working now. I was setting an empty string – IRPdevelop Mar 13 '18 at 18:18
  • Gradle can't find it in the maven repo. – Johann May 11 '18 at 09:42
  • @AndroidDev the newest versions are available through jitpack https://jitpack.io/#simbiose/Encryption. Only the first version was released on maven. – ademar111190 May 14 '18 at 19:13
  • Is this library affected by https://android-developers.googleblog.com/2016/06/security-crypto-provider-deprecated-in.html ? – Cheok Yan Cheng Jun 30 '18 at 17:30
  • I guess yes it is, but I need to test @CheokYanCheng – ademar111190 Jun 30 '18 at 18:01
  • Is there a equivalent of this class in C#. I am porting some functionality from java to C# which uses this class. – Kamran Shahid Apr 02 '19 at 07:31
61

Java - encrypt / decrypt user name and password from a configuration file

Code from above link

DESKeySpec keySpec = new DESKeySpec("Your secret Key phrase".getBytes("UTF8"));
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey key = keyFactory.generateSecret(keySpec);
sun.misc.BASE64Encoder base64encoder = new BASE64Encoder();
sun.misc.BASE64Decoder base64decoder = new BASE64Decoder();
.........

// ENCODE plainTextPassword String
byte[] cleartext = plainTextPassword.getBytes("UTF8");      

Cipher cipher = Cipher.getInstance("DES"); // cipher is not thread safe
cipher.init(Cipher.ENCRYPT_MODE, key);
String encryptedPwd = base64encoder.encode(cipher.doFinal(cleartext));
// now you can store it 
......

// DECODE encryptedPwd String
byte[] encrypedPwdBytes = base64decoder.decodeBuffer(encryptedPwd);

Cipher cipher = Cipher.getInstance("DES");// cipher is not thread safe
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] plainTextPwdBytes = (cipher.doFinal(encrypedPwdBytes));
Community
  • 1
  • 1
Dead Programmer
  • 12,427
  • 23
  • 80
  • 112
  • Hmmm...I included library "rt.jar" in my "libs" folder (because of BASE64Encoder and BASE64Decoder), but it seems that Eclipse now crashes with message "Unable to execute dex: Java heap space. Java heap space". – svenkapudija Mar 08 '11 at 19:34
  • @svebee: Open your eclipse folder, then find eclipse.ini file and open it in an editor.Locate the following line: -Xms40m change it to: -Xms64m – Dead Programmer Mar 09 '11 at 06:34
  • Same problem again. Instead rt.jar I included Apache's Base64 codec (http://commons.apache.org/codec/). Now it's working with few changes in a code (like decodeBuffer to decode and so on). But yeah, that's it. Tnx :) – svenkapudija Mar 10 '11 at 18:06
  • Are you sure that class sun.misc.BASE64Encoder is available under Android? – Danubian Sailor Mar 02 '12 at 12:21
  • 12
    Since API level 8 you can simply use the static methods `Base64.encodeToString(cipher.doFinal(cleartext),Base64.DEFAULT)` and `Base64.decode(encryptedPwd, Base64.DEFAULT)` of the `android.util.Base64` class instead of importing an external library. – whlk Feb 02 '13 at 22:57
  • 13
    Nota bene: only the first 8 characters of the so-called "key phrase" are used! There is no exception or javadoc to remind you of this. So if you thought that "ACME Corp's secure pass phrase#!(&DSd19!" was secure, then know that anyone trying the string "ACME Cor" will decrypt your passwords. Also, this short key is the reason why DES is now considered insecure. – Aleksandr Dubinsky May 30 '13 at 20:39
  • 3
    Don't use this code! This code has serious security problems. DES is a low-security algorithm (AES is better). This code will encrypt with ECB mode, which is highly insecure. This code doesn't use a suitable key derivation function, such as PBKDF. It uses only the first 8 characters of the passphrase. This code fails to provide integrity protection (a MAC), which is important in practice. Do not use this code if you need secure cryptography. – D.W. Feb 09 '16 at 01:00
  • also have a look at my question http://stackoverflow.com/questions/38007478/encrypt-and-decrypt-string-using-chacha20 – Zar E Ahmer Jun 24 '16 at 09:20
  • @DeadProgrammer Hello Sir I want create password protected android application for File(pdf,images,audio,video etc). please provide some documentation. – Shree Prakash Jan 12 '17 at 12:32
  • "in Android N we are deprecating the implementation of the SHA1PRNG algorithm and the Crypto provider altogether" Please follow the link for further information; https://android-developers.googleblog.com/2016/06/security-crypto-provider-deprecated-in.html – mavixce Jan 30 '17 at 13:01
  • 1
    > *I don't need extremely high security, it needs to be fast!* -OP – Stijn de Witt May 02 '17 at 09:25
  • @D.W. "Don't use this code! This code has serious security problems." - You see this comment posted on just about any SO topic that deals with ANY encryption algorithm. EVERY encryption algorithm has security problems. – Johann May 11 '18 at 09:30
  • @AndroidDev, That's not true, of course. There are ways to do it securely and ways to do it insecurely. [ECB](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#ECB) is [one of the worst ways](https://crypto.stackexchange.com/q/20941/351). I suggest doing some research before making statements like that. – D.W. May 11 '18 at 14:14
1

Simplest way is to add this JAVA library using Gradle:

compile 'se.simbio.encryption:library:2.0.0'

You can use it as simple as this:

Encryption encryption = Encryption.getDefault("Key", "Salt", new byte[16]);
String encrypted = encryption.encryptOrNull("top secret string");
String decrypted = encryption.decryptOrNull(encrypted);
eyadMhanna
  • 2,412
  • 3
  • 31
  • 49
EKN
  • 1,886
  • 1
  • 16
  • 29
  • 1
    that's a java library, not a 'gradle library'. You posted the gradle string to add a dependency. Not everyone uses gradles – spy Jan 13 '17 at 01:59
-9

If you are using Android then you can use android.util.Base64 class.

Encode:

passwd = Base64.encodeToString( passwd.getBytes(), Base64.DEFAULT );

Decode:

passwd = new String( Base64.decode( passwd, Base64.DEFAULT ) );

A simple and fast single line solution.

Sileria
  • 15,223
  • 4
  • 49
  • 28
  • 79
    Base64 is not encryption. DO NOT DO THIS. – Timmmm Feb 26 '13 at 16:02
  • 10
    Yes this is not real encryption, It is fast and easy way of hiding your password from being exposed in a readable format or protecting it from amateur hackers. So depending on how strong security you need, you can choose between fast and easy password hiding vs. a real strong and heavy encryption algorithm. – Sileria Mar 29 '13 at 12:01
  • 11
    @Mobistry amateur hackers will do base 64 decrypt as their very *first* attempt. don't use base 64 for anything security related. – Eran Medan Jul 02 '13 at 17:45
  • 1
    Use it if you need to transfer data in a portable way, nothing else. – Mustafa Mar 05 '14 at 16:32
  • 1
    Good enough to hide some strings from your competitors' fast analytics, so thanks from my side for this simple piece of code. – Martin L. Mar 10 '14 at 13:31
  • Its not an encryption method though, but good way to encode and decode. No need for any key management. It was useful for my case. – Bala Vishnu Feb 14 '15 at 17:35
  • Yes, it's not encryption. But for my case of only wanting to obfuscate a configuration file WITHOUT PASSSWORD it would have been ok. Anyways, the solution of ademar is almost as easy why I use his library. – Tobias Feb 10 '16 at 02:50