Es wurde ursprünglich auf Nuggets gepostet, deshalb habe ich es hierher verschoben. WeChat-Miniprogramme werden verschlüsselt auf dem PC gespeichert. Öffnet man sie direkt, sieht man keine nützlichen Informationen. Sie müssen entschlüsselt werden, bevor man den konkreten Inhalt des Pakets sehen kann. Dieser Artikel verwendet Node.js zur Implementierung des Entschlüsselungsalgorithmus, der hauptsächlich die Verwendung von drei Paketen beinhaltet: Crypto, Commander und Chalk. Wo ist der Quellcode des Applets?Auf dem PC geöffnete Miniprogramme werden am Standardspeicherort lokaler WeChat-Dateien zwischengespeichert. Sie können sie über WeChat PC => Mehr => Einstellungen anzeigen: Rufen Sie den Ordner /WeChat Files/WeChat Files/Applet im Standardspeicherort auf. Dort sehen Sie eine Reihe von Dateien mit dem Präfix wx (der Dateiname ist eigentlich die App-ID des Miniprogramms). Dies sind die Miniprogramme, die wir geöffnet haben: Wenn wir den Ordner eines der Miniprogramme öffnen, sehen wir einen Ordner, dessen Name aus einer Zahlenfolge besteht. Klicken Sie in diesen Ordner und Sie sehen eine Datei __APP__.wxapkg. Das ist der Code, der dem Applet entspricht: Als wir die Datei öffneten, fanden wir jedoch Folgendes: Daraus lässt sich WTF erkennen 🔨. Offensichtlich ist diese Datei verschlüsselt und muss entschlüsselt werden, um zu sehen, was wir sehen möchten. Wie werden PC-Miniprogramme verschlüsselt?Hier ist ein Verweis auf den PC-seitigen wxapkg-Entschlüsselungscode, der von einem großen Kerl in der Sprache Go geschrieben wurde. Um es in Ordnung zu bringen, der Verschlüsselungsprozess ist wie folgt: Zunächst wird der Klartextcode beim 1024. Byte in zwei Hälften geteilt. Die erste Hälfte wird mit AES im CBC-Modus verschlüsselt, die zweite Hälfte wird direkt XOR-verknüpft. Zum Schluss verketten Sie die beiden verschlüsselten Abschnitte und schreiben eine feste Zeichenfolge davor: „V1MMWX“. Wenn wir also die Datei __APP__.wxapkg öffnen, sehen wir den verschlüsselten Code. Wenn wir ihn wiederherstellen möchten, müssen wir ihn Schritt für Schritt von hinten nach vorne verschieben. EntschlüsselungsideenVorverarbeitungWir verwenden node.js, um ein Dekodierungsprogramm zu schreiben. Gemäß dem obigen Verschlüsselungsprozess lesen wir zuerst die verschlüsselte Datei und entfernen die feste Zeichenfolge der ersten 6 Bytes. Da die Anzahl der Bits vor und nach der AES-Verschlüsselung und dem XOR gleich ist, können wir den verschlüsselten 1024-Byte-Header und den verschlüsselten Tail erhalten: const fs = require('fs').versprechen; ... const buf = await fs.readFile(pkgsrc); // Den ursprünglichen Puffer lesen const bufHead = buf.slice(6, 1024 + 6); const bufTail = buf.slice(1024 + 6); Verschlüsselter HeaderUm diese 1024 Bytes Klartext zu erhalten, müssen wir den Anfangsvektor iv der AES-Verschlüsselung und einen 32-Bit-Schlüssel kennen. Da wir wissen, dass der 16-Byte-Anfangsvektor iv die Zeichenfolge „der iv: 16 Bytes“ ist, müssen wir als Nächstes den 32-Bit-Schlüssel berechnen, der vom pbkdf2-Algorithmus abgeleitet wird. pbkdf2 (Password-Based Key Derivation Function) ist eine Funktion zum Generieren eines Schlüssels. Sie verwendet eine pseudozufällige Funktion, verwendet das ursprüngliche Passwort und Salt als Eingabe und erhält den Schlüssel durch kontinuierliche Iteration. In der Kryptobibliothek sieht die Funktion pbkdf2 folgendermaßen aus: const crypto = erforderlich('Krypto'); ... crypto.pbkdf2(Passwort, Salt, Iterationen, Keylen, Digest, Callback) Die Parameter sind: Originalpasswort, Salt-Wert, Anzahl der Iterationen, Schlüssellänge, Hash-Algorithmus und Rückruffunktion. Es ist bekannt, dass das Salt „am salzigsten“ ist, das ursprüngliche Passwort die ID des WeChat-Applets ist (d. h. der Ordnername, der mit wx beginnt), die Anzahl der Iterationen 1000 beträgt und der Hash-Algorithmus sha1 ist. Daher können wir den Code zur Berechnung des Schlüssels schreiben: crypto.pbkdf2(wxid, salt, 1000, 32, 'sha1', (err, dk) => { wenn (Fehler) { // Fehler} // dk ist der berechnete Schlüssel}) Nachdem wir den Schlüssel und den Anfangsvektor iv haben, können wir mit der Entschlüsselung des Geheimtextes beginnen. Der AES-Verschlüsselungsalgorithmus ist ein asymmetrischer Verschlüsselungsalgorithmus. Sein Schlüssel ist in einen öffentlichen und einen privaten Schlüssel aufgeteilt, die nur der Benutzer kennt. Mit dem öffentlichen Schlüssel kann jeder verschlüsseln, den Klartext entschlüsseln kann jedoch nur der Besitzer des privaten Schlüssels. Der vom Applet verwendete Verschlüsselungsalgorithmus ist AES im CBC-Modus (Cipher Block Chaining). Das heißt, beim Verschlüsseln wird der Klartext zunächst in Blöcke aufgeteilt, dann wird jeder Block mit dem verschlüsselten Geheimtext des vorherigen Blocks per XOR verknüpft und anschließend wird der öffentliche Schlüssel zum Verschlüsseln verwendet, um den Geheimtext jedes Blocks zu erhalten. Für den ersten Klartextblock wird, da er im vorherigen Klartextblock nicht vorhanden ist, ein XOR-Vorgang mit dem Anfangsvektor iv durchgeführt und anschließend mit dem öffentlichen Schlüssel verschlüsselt. Bei der Implementierung müssen wir nur die von Crypto bereitgestellte Entschlüsselungsfunktion aufrufen. Wir wissen, dass es zu den AES-Algorithmen je nach Schlüssellänge AES128, AES192 und AES256 gibt. Rückblickend ist unser Schlüssel 32 Bytes oder 256 Bits lang, also sollten wir offensichtlich AES256 verwenden. Zusammenfassend können wir den Entschlüsselungscode schreiben: const decipher = crypto.createDecipheriv('aes-256-cbc', dk, iv); const originalHead = Buffer.alloc(1024, decipher.update(bufHead)); Davon sind originalHead die ersten 1024 Bytes des gewünschten Klartexts. Wir können es ausdrucken und sehen: Hmm ... das ist ein bisschen interessant. Verschlüsselter SchwanzteilDieser Teil ist einfach. Da die XOR-Operation reflexiv ist, müssen wir lediglich die Anzahl der Ziffern in der Applet-ID ermitteln, um den XOR-Schlüssel zu erhalten, und ihn dann mit dem Geheimtext XOR-verknüpfen, um den Originaltext zu erhalten: const xorKey = wxid.length < 2 ? 0x66 : wxid.charCodeAt(wxid.length - 2); const Schwanz = []; für(lass i = 0; i < bufTail.length; ++i){ tail.push(xorKey ^ bufTail[i]); } const originalTail = Buffer.from(tail); Verketten Sie den Klartext im Kopfteil mit dem Klartext im Endteil und schreiben Sie sie dann in Binärform in die Datei, um den endgültigen Klartext zu erhalten. Sei schönerBasierend auf der obigen Beschreibung können wir unseren gesamten Entschlüsselungsprozess in einer Blackbox zusammenfassen: KommandantWir können die Commander-Bibliothek verwenden, um dem Programm zu ermöglichen, die ID und das Chiffretextpaket des Applets direkt von der Befehlszeile zu lesen. Commander ist eine Node.JS-Befehlszeilenschnittstellenlösung, mit der Sie einfach Ihre eigenen CLI-Befehle definieren können. Beispielsweise für den folgenden Code: const-Programm = erforderlich('Kommandant'); ... Programm .Befehl('entschlüsseln <wxid> <src> [dst]') .description('PC-WeChat-Applet-Paket dekodieren') .action((wxid, src, dst) => { wxmd(wxid, Quelle, Ziel); }) Programmversion('1.0.0') .usage("entschlüsseln <wxid> <src> [dst]") .parse(Prozess.argv); Ich habe einen Befehl „decry <wxid> <src> [dst]“ definiert, wobei spitze Klammern erforderliche Parameter und eckige Klammern optionale Parameter darstellen. Beschreibung enthält den Beschreibungstext zu diesem Befehl und die Aktion besteht darin, diesen Befehl auszuführen. Nachdem Sie den Code mithilfe von Node in der Konsole ausgeführt haben, wird die folgende Schnittstelle angezeigt: Anschließend können wir gemäß den Eingabeaufforderungen die Parameter zur Entschlüsselung eingeben. Die chinesische Dokumentation von commander.js finden Sie hier. KreideUm unserer Konsole einen Hauch von Farbe zu verleihen, können wir chalk.js verwenden, um die Ausgabe zu verschönern. Auch die grundsätzliche Anwendung von Kreide ist relativ einfach: const Kreide = erforderlich('Kreide'); ... Konsole.log(Kreide.grün('grün')) Auf diese Weise können wir der schwarz-weißen Konsole einen Hauch von Grün verleihen und den Traum des Pandas verwirklichen: Darüber hinaus können wir auch es6-String-Tag-Vorlagen verwenden, um Kreide bequemer zu nutzen. Weitere Einzelheiten finden Sie in der offiziellen Chalk-Dokumentation. QuellcodeDer Code wurde auf GitHub und Gitee veröffentlicht, Sie können darauf verweisen~ Klicken Sie hier für GitHub und hier für Gitee Dies ist das Ende dieses Artikels über die Entschlüsselung des WeChat-Applet-Pakets auf dem PC in node.js. Weitere relevante Inhalte zur Entschlüsselung des Node.js-WeChat-Applets finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder durchsuchen Sie die folgenden verwandten Artikel weiter. Ich hoffe, dass jeder 123WORDPRESS.COM in Zukunft unterstützen wird! Das könnte Sie auch interessieren:
|
<<: Beispielcode zur Implementierung der automatischen Markdown-Nummerierung mit reinem CSS
>>: Die CSS-Priorität der Webseite wird für Sie ausführlich erklärt
Das Hauptsymptom des Konflikts besteht darin, dass...
1. Klicken Sie auf den Server-Host und dann in de...
Originalartikel, bei Nachdruck bitte Autor und Qu...
Konfigurieren von Java-Umgebungsvariablen Hier we...
Neo4j (eines der NoSQL-Modelle) ist eine leistung...
Vorwort MySQL unterstützt viele Arten von Tabelle...
Inhaltsverzeichnis 1. Workflow ausführen 2. Grund...
Vorwort Nachdem das Projekt auf .net Core migrier...
Nehmen wir ein Benutzerverwaltungssystem an, bei ...
Der zu erzielende Effekt In vielen Fällen überwac...
Grid ist ein zweidimensionales Rasterlayoutsystem...
Inhaltsverzeichnis 1. Beobachtbar 2. Funktionen h...
Inhaltsverzeichnis 1. Einleitung 2. Installation ...
1. Nach der Installation der Windows-Version von ...
In Sprachen werden häufig Makros zur Implementier...