这个smali class 解密数据吗?它使用什么加密?
Does this smali class decrypt data? what encryption is it using?
问:这个smali class能解密数据吗?它使用什么加密?
我需要帮助找出这段代码用来解密它接收到的文件文本的内容吗?
加密文本按预期打印出来,乱七八糟,有没有办法使用我需要帮助理解的信息手动解密文本?
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();
}
您问题的(简短)答案是肯定的。
您的 class(方法 wr)正在使用 固定 密钥加密字符串(包装在 StringBuilder 中)并将密文保存到光盘上的文件中。另一种方法(rf)是用密文读取文件,用固定密钥解密并打印
解密/明文到控制台。
这些是您 class 中的 5 种方法,并附有简短说明:
gk = 为 AES en-/decryption
生成一个 fixed 16 字节(128 位)长密钥
ef = 用生成的密钥加密字节数组
df = 用生成的密钥解密字节数组
wr = 将加密的字节数组(使用方法 ef)写入光盘上的文件
rf = 读取文件内容到字节数组,用 df 方法解密并显示解密文本
class 使用 AES/ECB/PKCS5PADDING 模式进行加密(我在 OpenJDK 11 上手动完成解密,所以可能该模式与您的加密服务提供商在 Android 上有另一个名称) .方法 ef + df 中的初始化
"Cipher.getInstance("AES")" 导致 "standard" ECB-PKCS5PADDING 模式不安全,不应再使用 。
如果您创建了一个密文文件"cipher.dat",您可以使用这个简单的程序来解密内容并将其显示在控制台上(没有适当的异常处理...):
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" +
"");
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;
}
}
示例输出:
Simple decryption method for
decrypted text: This text needs to get encrypted
问:这个smali class能解密数据吗?它使用什么加密?
我需要帮助找出这段代码用来解密它接收到的文件文本的内容吗? 加密文本按预期打印出来,乱七八糟,有没有办法使用我需要帮助理解的信息手动解密文本?
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();
}
您问题的(简短)答案是肯定的。
您的 class(方法 wr)正在使用 固定 密钥加密字符串(包装在 StringBuilder 中)并将密文保存到光盘上的文件中。另一种方法(rf)是用密文读取文件,用固定密钥解密并打印 解密/明文到控制台。
这些是您 class 中的 5 种方法,并附有简短说明:
gk = 为 AES en-/decryption
生成一个 fixed 16 字节(128 位)长密钥ef = 用生成的密钥加密字节数组
df = 用生成的密钥解密字节数组
wr = 将加密的字节数组(使用方法 ef)写入光盘上的文件
rf = 读取文件内容到字节数组,用 df 方法解密并显示解密文本
class 使用 AES/ECB/PKCS5PADDING 模式进行加密(我在 OpenJDK 11 上手动完成解密,所以可能该模式与您的加密服务提供商在 Android 上有另一个名称) .方法 ef + df 中的初始化 "Cipher.getInstance("AES")" 导致 "standard" ECB-PKCS5PADDING 模式不安全,不应再使用 。
如果您创建了一个密文文件"cipher.dat",您可以使用这个简单的程序来解密内容并将其显示在控制台上(没有适当的异常处理...):
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" +
"");
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;
}
}
示例输出:
Simple decryption method for
decrypted text: This text needs to get encrypted