001package com.gigya.android.sdk.utils;
002
003import android.annotation.SuppressLint;
004
005import com.gigya.android.sdk.GigyaLogger;
006import com.gigya.android.sdk.encryption.EncryptionException;
007
008import java.math.BigInteger;
009import java.nio.ByteBuffer;
010import java.nio.CharBuffer;
011import java.nio.charset.Charset;
012import java.util.Arrays;
013
014import javax.crypto.Cipher;
015import javax.crypto.SecretKey;
016
017public class CipherUtils {
018
019    public static String bytesToString(byte[] b) {
020        byte[] b2 = new byte[b.length + 1];
021        b2[0] = 1;
022        System.arraycopy(b, 0, b2, 1, b.length);
023        return new BigInteger(b2).toString(36);
024    }
025
026    public static byte[] stringToBytes(String s) {
027        byte[] b2 = new BigInteger(s, 36).toByteArray();
028        return Arrays.copyOfRange(b2, 1, b2.length);
029    }
030
031    public static byte[] toBytes(char[] chars) {
032        final CharBuffer charBuffer = CharBuffer.wrap(chars);
033        final ByteBuffer byteBuffer = Charset.forName("UTF-8").encode(charBuffer);
034        final byte[] bytes = Arrays.copyOfRange(byteBuffer.array(), byteBuffer.position(), byteBuffer.limit());
035        Arrays.fill(charBuffer.array(), '\u0000'); // clear the cleartext
036        Arrays.fill(byteBuffer.array(), (byte) 0); // clear the cipher text
037        return bytes;
038    }
039
040    public static char[] toChars(byte[] bytes) {
041        final Charset charset = Charset.forName("UTF-8");
042        final ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
043        final CharBuffer charBuffer = charset.decode(byteBuffer);
044        final char[] chars = Arrays.copyOf(charBuffer.array(), charBuffer.limit());
045        Arrays.fill(charBuffer.array(), '\u0000'); // clear the cleartext
046        Arrays.fill(byteBuffer.array(), (byte) 0); // clear the cipher text
047        return chars;
048    }
049
050    public static String encrypt(String plain, String algorithm, SecretKey secretKey) throws EncryptionException {
051        GigyaLogger.debug("CipherUtils", algorithm + " encrypt: ");
052        try {
053            @SuppressLint("GetInstance") final Cipher aesCipher = Cipher.getInstance(algorithm);
054            aesCipher.init(Cipher.ENCRYPT_MODE, secretKey);
055            byte[] byteCipherText = aesCipher.doFinal(plain.getBytes());
056            return CipherUtils.bytesToString(byteCipherText);
057        } catch (Exception ex) {
058            ex.printStackTrace();
059            throw new EncryptionException("Session encryption exception", ex.getCause());
060        }
061    }
062
063    public static String decrypt(String encrypted, String algorithm, SecretKey secretKey) throws EncryptionException {
064        GigyaLogger.debug("CipherUtils", algorithm + " decrypt: ");
065        try {
066            @SuppressLint("GetInstance") final Cipher aesCipher = Cipher.getInstance(algorithm);
067            aesCipher.init(Cipher.DECRYPT_MODE, secretKey);
068            byte[] encPLBytes = CipherUtils.stringToBytes(encrypted);
069            byte[] bytePlainText = aesCipher.doFinal(encPLBytes);
070            return new String(bytePlainText);
071        } catch (Exception ex) {
072            ex.printStackTrace();
073            throw new EncryptionException("Session encryption exception", ex.getCause());
074        }
075    }
076
077}