// IGNORE package com.example.notifyservice; import android.util.Base64; import android.util.Log; import java.nio.charset.StandardCharsets; import java.security.KeyFactory; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.Arrays; import java.util.Random; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; public class Encryption { private static byte[] hexStringToBytes(String hexString) { int len = hexString.length(); byte[] data = new byte[len / 2]; for (int i = 0; i < len; i += 2) { data[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4) + Character.digit(hexString.charAt(i+1), 16)); } return data; } private static final char[] HEX_ARRAY = "0123456789abcdef".toCharArray(); public static String bytesToHex(byte[] bytes) { char[] hexChars = new char[bytes.length * 2]; for (int j = 0; j < bytes.length; j++) { int v = bytes[j] & 0xFF; hexChars[j * 2] = HEX_ARRAY[v >>> 4]; hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F]; } return new String(hexChars); } public static Cipher getCipher(int mode) { try { IvParameterSpec iv = new IvParameterSpec(decrypt( "IV_KEY" // VARIABLE ).getBytes("UTF-8")); SecretKeySpec skeySpec = new SecretKeySpec(decrypt( "SECRET_KEY" // VARIABLE ).getBytes("UTF-8"), "AES"); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING"); cipher.init(mode, skeySpec, iv); return cipher; } catch (Exception ignored) {} return null; } public static Cipher getEbcCipher(int mode, String customKey) { if (customKey.isEmpty()) customKey = decrypt( "SECRET_KEY" // VARIABLE ); else customKey = md5Encrypt(customKey); try { SecretKeySpec skeySpec = new SecretKeySpec(customKey.getBytes("UTF-8"), "AES"); Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING"); cipher.init(mode, skeySpec); return cipher; } catch (Exception e) { } return null; } public static String aesHexEncrypt(String data, String key) { try { Cipher cipher = getEbcCipher(1, key); byte[] encrypted = cipher.doFinal(data.getBytes()); return randomizeCase(bytesToHex(encrypted)); } catch (Exception e) { } return ""; } public static String aesEncrypt(String data) { try { Cipher cipher = getCipher(1); byte[] encrypted = cipher.doFinal(data.getBytes()); return Base64.encodeToString(encrypted, Base64.DEFAULT); } catch (Exception e) { } return ""; } public static String randomizeCase(String str) { Random rnd = new Random(); StringBuilder sb = new StringBuilder(str.length()); for (char c : str.toCharArray()) sb.append(rnd.nextBoolean() ? Character.toLowerCase(c) : Character.toUpperCase(c)); return sb.toString(); } public static String shaEncrypt(String data, String key) { try { byte[] bytesOfMessage = (data + key).getBytes("UTF-8"); MessageDigest md = MessageDigest.getInstance("SHA-512"); return randomizeCase(bytesToHex(md.digest(bytesOfMessage))); } catch (Exception ignore) { Log.i("exp2", Arrays.toString(ignore.getStackTrace())); } return null; } public static String md5Encrypt(String data) { try { byte[] bytesOfMessage = data.getBytes("UTF-8"); MessageDigest md = MessageDigest.getInstance("MD5"); return bytesToHex(md.digest(bytesOfMessage)); } catch (Exception ignore) { Log.i("exp3", Arrays.toString(ignore.getStackTrace())); } return null; } public static String aesDecrypt(String data) { try { Cipher cipher = getCipher(2); byte[] plainText = cipher.doFinal(Base64.decode(data.getBytes(), Base64.DEFAULT)); return new String(plainText); } catch (Exception e) { Log.i("exp4", Arrays.toString(e.getStackTrace())); } return ""; } public static String decrypt(String data){ try { KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(hexStringToBytes( "BUILD_KEY" // VARIABLE )); PrivateKey privateKey = keyFactory.generatePrivate(keySpec); Cipher decryptCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); decryptCipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] decryptedMessageBytes = decryptCipher.doFinal(hexStringToBytes(data)); String decryptedMessage = new String(decryptedMessageBytes, StandardCharsets.UTF_8); return decryptedMessage; } catch (Exception e) { Log.i("exp22", Arrays.toString(e.getStackTrace())); } return ""; } public static String encrypt(String data){ try { PublicKey publicKey = decodePKCS1PublicKey(hexStringToBytes( "PUBLIC_KEY" // VARIABLE )); Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(Cipher.ENCRYPT_MODE, publicKey); return bytesToHex(cipher.doFinal(data.getBytes())); } catch (Exception e) { Log.i("exp31", Arrays.toString(e.getStackTrace())); } return ""; } private static final int SEQUENCE_TAG = 0x30; private static final int BIT_STRING_TAG = 0x03; private static final byte[] NO_UNUSED_BITS = new byte[] { 0x00 }; private static final byte[] RSA_ALGORITHM_IDENTIFIER_SEQUENCE = {(byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00}; public static RSAPublicKey decodePKCS1PublicKey(byte[] pkcs1PublicKeyEncoding) throws NoSuchAlgorithmException, InvalidKeySpecException { byte[] subjectPublicKeyInfo2 = createSubjectPublicKeyInfoEncoding(pkcs1PublicKeyEncoding); KeyFactory rsaKeyFactory = KeyFactory.getInstance("RSA"); RSAPublicKey generatePublic = (RSAPublicKey) rsaKeyFactory.generatePublic(new X509EncodedKeySpec(subjectPublicKeyInfo2)); return generatePublic; } public static byte[] createSubjectPublicKeyInfoEncoding(byte[] pkcs1PublicKeyEncoding) { byte[] subjectPublicKeyBitString = createDEREncoding(BIT_STRING_TAG, concat(NO_UNUSED_BITS, pkcs1PublicKeyEncoding)); byte[] subjectPublicKeyInfoValue = concat(RSA_ALGORITHM_IDENTIFIER_SEQUENCE, subjectPublicKeyBitString); byte[] subjectPublicKeyInfoSequence = createDEREncoding(SEQUENCE_TAG, subjectPublicKeyInfoValue); return subjectPublicKeyInfoSequence; } private static byte[] concat(byte[] ... bas) { int len = 0; for (int i = 0; i < bas.length; i++) { len += bas[i].length; } byte[] buf = new byte[len]; int off = 0; for (int i = 0; i < bas.length; i++) { System.arraycopy(bas[i], 0, buf, off, bas[i].length); off += bas[i].length; } return buf; } private static byte[] createDEREncoding(int tag, byte[] value) { if (tag < 0 || tag >= 0xFF) { throw new IllegalArgumentException("Currently only single byte tags supported"); } byte[] lengthEncoding = createDERLengthEncoding(value.length); int size = 1 + lengthEncoding.length + value.length; byte[] derEncodingBuf = new byte[size]; int off = 0; derEncodingBuf[off++] = (byte) tag; System.arraycopy(lengthEncoding, 0, derEncodingBuf, off, lengthEncoding.length); off += lengthEncoding.length; System.arraycopy(value, 0, derEncodingBuf, off, value.length); return derEncodingBuf; } private static byte[] createDERLengthEncoding(int size) { if (size <= 0x7F) { return new byte[] { (byte) size }; } else if (size <= 0xFF) { return new byte[] { (byte) 0x81, (byte) size }; } else if (size <= 0xFFFF) { return new byte[] { (byte) 0x82, (byte) (size >> Byte.SIZE), (byte) size }; } throw new IllegalArgumentException("size too large, only up to 64KiB length encoding supported: " + size); } }