Hola, estoy desarrollando una aplicación personal donde se obtiene los mensajes de WhatsApp, obtuve el KEY desde mi emulador y si la base de datos msgstore.db.crypt12 se genera del emulador y lo puedes des-encriptar pero si tomo la que esta en el teléfono no alguna ayuda.
import android.content.Context;
import android.os.AsyncTask;
import android.os.Environment;
import android.util.Log;
import android.widget.Toast;
import androidx.fragment.app.FragmentActivity;
import com.autonica.myserviceappclient.data.database.ConexionSQLiteDB;
import com.autonica.myserviceappclient.data.model.AuthenticateModel;
import com.autonica.myserviceappclient.data.model.User;
import org.spongycastle.jce.provider.BouncyCastleProvider;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.security.Security;
import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import retrofit2.Call;
public class decrypt12 {
static{
Security.insertProviderAt(new org.spongycastle.jce.provider.BouncyCastleProvider(), 1);
}
public static String decrypt(String KeyFile, String C12File, String SQLFile) throws Exception {
final File tempFile = new File(System.getProperty("java.io.tmpdir") + "/"
+ (int) (System.currentTimeMillis() / 1000L) + "-msgstore.enc");
if (!new File(KeyFile).isFile())
quit("The specified input key file does not exist.");
else if (new File(KeyFile).length() != 158)
quit("The specified input key file is invalid.");
else if (!new File(C12File).isFile())
quit("The specified input crypt12 file does not exist.");
InputStream KeyIn = new FileInputStream(KeyFile);
InputStream WdbIn = new BufferedInputStream(new FileInputStream(C12File));
byte[] KeyData = new byte[158];
KeyIn.read(KeyData);
byte[] T1 = new byte[32];
System.arraycopy(KeyData, 30, T1, 0, 32);
byte[] KEY = new byte[32];
System.arraycopy(KeyData, 126, KEY, 0, 32);
KeyIn.close();
byte[] C12Data = new byte[67];
WdbIn.read(C12Data);
byte[] T2 = new byte[32];
System.arraycopy(C12Data, 3, T2, 0, 32);
byte[] IV = new byte[16];
System.arraycopy(C12Data, 51, IV, 0, 16);
if (!new String(T1, 0, T1.length, "ASCII").equals(new String(T2, 0, T2.length, "ASCII")))
quit("Key file mismatch or crypt12 file is corrupt.");
int InputLength = WdbIn.available();
RandomAccessFile raf = new RandomAccessFile(tempFile, "rw");
byte[] tempBuffer = new byte[1024];
int I;
while ((I = WdbIn.read(tempBuffer)) != -1)
raf.write(tempBuffer, 0, I);
raf.setLength(InputLength - 20);
raf.close();
WdbIn.close();
InputStream PdbSt = new BufferedInputStream(new FileInputStream(tempFile));
Cipher cipher;
Security.addProvider(new BouncyCastleProvider());
//cipher = Cipher.getInstance("AES/GCM/NoPadding", "BC"); // BouncyCastle
cipher = Cipher.getInstance("AES/GCM/NoPadding", "SC"); // SpongyCastle (Android)
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(KEY, "AES"), new IvParameterSpec(IV));
CipherInputStream CipherStream = new CipherInputStream(PdbSt, cipher);
InflaterInputStream CryptOutput = new InflaterInputStream(CipherStream, new Inflater(false));
try {
FileOutputStream InflateBuffer = new FileOutputStream(SQLFile);
int N = 0;
byte[] CryptBuffer = new byte[8192];
while ((N = CryptOutput.read(CryptBuffer)) != -1) {
InflateBuffer.write(CryptBuffer, 0, N);
}
InflateBuffer.close();
} catch (IOException ex) {
quit("Fatal error:" + ex);
}
try {
CipherStream.close();
}catch (Exception e){
quit("Fatal error:" + e);
}
tempFile.delete();
InputStream SqlDB = new FileInputStream(SQLFile);
byte[] SqlData = new byte[6];
SqlDB.read(SqlData);
byte[] MS = new byte[6];
System.arraycopy(SqlData, 0, MS, 0, 6);
SqlDB.close();
if (!new String(MS, 0, MS.length, "ASCII").toLowerCase().equals("sqlite")) {
new File(SQLFile).delete();
return "El descifrado del archivo crypt12 ha fallado.";
}
else{
return "El descifrado del archivo crypt12 fue exitoso.";
}
}
public void ejcutarLectura(FragmentActivity context){
/*LecturaAsyncTask task = new LecturaAsyncTask(context);
task.equals(null);*/
new LongOperation(context).execute("");
}
private class LongOperation extends AsyncTask<String, Void, String> {
//private String ruta_Wht = Environment.getExternalStoragePublicDirectory("WhatsApp") + "/Databases/msgstore.db.crypt12";
//private String ruta_key = Environment.getExternalStoragePublicDirectory("WhatsApp") + "/Databases/key50558090693";
//private String ruta_SQL = Environment.getExternalStoragePublicDirectory("WhatsApp") + "/Databases/msgstore.db";
private String ruta_Wht = Environment.getExternalStoragePublicDirectory("WhatsApp") + "/Databases2/msgstore.db.crypt12";
private String ruta_key = Environment.getExternalStoragePublicDirectory("WhatsApp") + "/Databases2/key50588815240";
private String ruta_SQL = Environment.getExternalStoragePublicDirectory("WhatsApp") + "/Databases2/msgstore.db";
private FragmentActivity context;
public LongOperation(FragmentActivity context) {
this.context = context;
}
@Override
protected String doInBackground(String... params) {
boolean d = true;
String lista = "";
File dir0 = new File(ruta_Wht);
if( !dir0.exists() ) {
lista = "respaldo de WhatsApp";
d = false;
}
File dir1 = new File(ruta_key);
if( !dir1.exists() ) {
if(lista.equals("")){
lista = "Llave de Acceso.";
}else
lista = lista + ", Llave de Acceso.";
d = false;
}
File dir2 = new File(ruta_SQL);
if( !dir2.exists() ) {
try {
if(dir2.createNewFile()){
quit("Unidad fue creada : "+ruta_SQL);
d = true;
}else{
lista = "No tiene permiso de creacion de archivo";
quit("Error : "+lista);
d = false;
}
} catch (IOException e) {
//e.printStackTrace();
quit("Error : "+e.getMessage());
lista = "No tiene permiso de creacion de archivo";
d = false;
}
}
if(d){
try {
String t = decrypt(ruta_key,ruta_Wht,ruta_SQL);
if(t.equals("El descifrado del archivo crypt12 fue exitoso.")){
ConexionSQLiteDB db = new ConexionSQLiteDB(context,ruta_SQL);
db.prueba();
}
return t;
} catch (Exception e) {
e.printStackTrace();
return "Fallo";
}
}else{
return "Falta los siguientes archivos: "+lista;
}
}
@Override
protected void onPostExecute(String us) {
Toast.makeText(context, us,Toast.LENGTH_SHORT).show();
}
}
private static void quit(String Msg) {
System.out.println(Msg+"\n");
}
}