Q: Does this smali class decrypt data? what encryption is it using?
I need help finding out what this code uses to decrypt the file text it receives? the encrypted text prints out as expected in a jumbled mess, is there a way to manually decrypt the text using the information I need help understanding?
package utils;
import android.util.Log;
import com.crashlytics.android.Crashlytics;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.io.FileUtils;
public class EFileIO {
private static byte[] df(byte[] var0, byte[] var1) throws Exception {
SecretKeySpec var2 = new SecretKeySpec(var0, "AES");
Cipher var3 = Cipher.getInstance("AES");
var3.init(2, var2);
return var3.doFinal(var1);
}
private static byte[] ef(byte[] var0, byte[] var1) throws Exception {
SecretKeySpec var2 = new SecretKeySpec(var0, "AES");
Cipher var3 = Cipher.getInstance("AES");
var3.init(1, var2);
return var3.doFinal(var1);
}
private static byte[] gk(String var0) throws Exception {
byte[] var1 = var0.getBytes("UTF-8");
KeyGenerator var2 = KeyGenerator.getInstance("AES");
SecureRandom var3 = SecureRandom.getInstance("SHA1PRNG", "Crypto");
var3.setSeed(var1);
var2.init(128, var3);
return var2.generateKey().getEncoded();
}
public static String rf(File var0) {
String var1 = "";
String var3;
String var5;
try {
byte[] var2 = df(gk("AIzaSyDVQJ323-Th1pPJIcDrSt0KYFMTuLJR7Vw"), FileUtils.readFileToByteArray(var0));
var3 = new String(var2, "UTF-8");
} catch (Exception var4) {
Crashlytics.log(6, "EFILEIO.java", "rf, mf.getName(): " + var0.getName());
Crashlytics.logException(var4);
var4.printStackTrace();
var5 = var1;
return var5;
}
var5 = var3;
return var5;
}
public static void wr(StringBuilder var0, File var1) {
try {
FileOutputStream var3 = new FileOutputStream(var1);
BufferedOutputStream var2 = new BufferedOutputStream(var3);
byte[] var5 = ef(gk("AIzaSyDVQJ323-Th1pPJIcDrSt0KYFMTuLJR7Vw"), var0.toString().trim().getBytes("UTF-8"));
StringBuilder var6 = new StringBuilder();
Log.e("FileIo", var6.append("wr: content ").append(var5).toString());
var2.write(var5);
var2.flush();
var2.close();
} catch (Exception var4) {
Crashlytics.log(6, "EFILEIO.java", "wr, mf.getName(): " + var1.getName());
Crashlytics.logException(var4);
var4.printStackTrace();
}
The (short) answer to your question is YES.
Your class (method wr) is encrypting a String (wrapped in a StringBuilder) with a fixed key and saves the ciphertext to a file on the disc. Another method (rf) is reading the file with the ciphertext, decrypts it with the fixed key and prints the decrypted / plaintext to the console.
These are the 5 methods in your class with a short description:
gk = generates a fixed 16 byte (128 bit) long key for AES en-/decryption
ef = encrypts a byte array with the generated key
df = decrypts a byte array with the generated key
wr = writes the encrypted byte array (using method ef) to a file on the disc
rf = reads the contents of a file to a byte array, decrypts it with method df and shows the decrypted text
The class uses the AES/ECB/PKCS5PADDING mode for encryption (I done the decryption manually on OpenJDK 11, so maybe the mode has another name with your crypto service provider on Android). The initialisation in methods ef + df with "Cipher.getInstance("AES")" results in the "standard" ECB-PKCS5PADDING mode which is insecure and should be no longer used.
If you created a ciphertextfile "cipher.dat" you can use this simple program to decrypt the content and show it on the console (there is no proper exception handling...):
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
public class SimpleDecryption {
public static void main(String[] args) throws InvalidKeyException, NoSuchPaddingException, NoSuchAlgorithmException, IOException, BadPaddingException, IllegalBlockSizeException {
System.out.println("Simple decryption method for\n" +
"https://stackoverflow.com/questions/140131/convert-a-string-representation-of-a-hex-dump-to-a-byte-array-using-java");
String filename = "cipher.dat";
byte[] fixedKey = hexStringToByteArray("e409c02fb48745a14f5e1c03e3c6f0ca");
Cipher aesCipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
SecretKeySpec secretKeySpec = new SecretKeySpec(fixedKey, "AES");
aesCipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
System.out.println("decrypted text: " + new String(aesCipher.doFinal(Files.readAllBytes(Paths.get(filename))),"UTF-8"));
}
public static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i + 1), 16));
}
return data;
}
}
Sample output:
Simple decryption method for
https://stackoverflow.com/questions/140131/convert-a-string-representation-of-a-hex-dump-to-a-byte-array-using-java
decrypted text: This text needs to get encrypted