<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>dream</title>
        <link>https://paragraph.com/@lovefy</link>
        <description>undefined</description>
        <lastBuildDate>Wed, 29 Jul 2026 04:42:33 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <image>
            <title>dream</title>
            <url>https://storage.googleapis.com/papyrus_images/02144e0193e1f906ab285f7de84e2c903dd4975ee882bf329de90e085d41bd2a.jpg</url>
            <link>https://paragraph.com/@lovefy</link>
        </image>
        <copyright>All rights reserved</copyright>
        <item>
            <title><![CDATA[币安加持币圈热门APP(Wild Cash) 算法解密]]></title>
            <link>https://paragraph.com/@lovefy/app-wild-cash</link>
            <guid>5UE2zMMdXALiPZD0JCDz</guid>
            <pubDate>Fri, 25 Nov 2022 14:07:52 GMT</pubDate>
            <description><![CDATA[昨天一个名为Wild Cash的App火遍全网，每个群都在讨论它，币安加持，零撸赚钱，光这些就足够吸引眼球啦,用Fiddler 抓包发现是https协议的，但是经过了加密，好在APK没有加密，让我们来试试能不能找出算法可以看到，发包和收包都是加密过的用jadx解码然后搜索关键字定位到加密算法的地方，可以发现用的是aes算法package com.bo.hooked.common.d.d; import androidx.exifinterface.media.ExifInterface; import java.util.ArrayList; import java.util.List; import javax.crypto.Cipher; import javax.crypto.spec.GCMParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.android.codec.binary.Base64; import org.apache.commons.android...]]></description>
            <content:encoded><![CDATA[<p>昨天一个名为Wild Cash的App火遍全网，每个群都在讨论它，币安加持，零撸赚钱，光这些就足够吸引眼球啦,用Fiddler 抓包发现是https协议的，但是经过了加密，好在APK没有加密，让我们来试试能不能找出算法</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/0753b1ffe2702e288b8ebe371b45c4aeefc3ba3596eea76093e53de545f01b02.png" alt="可以看到，发包和收包都是加密过的" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="">可以看到，发包和收包都是加密过的</figcaption></figure><p>用jadx解码然后搜索关键字定位到加密算法的地方，可以发现用的是aes算法</p><pre data-type="codeBlock" text="package com.bo.hooked.common.d.d;

import androidx.exifinterface.media.ExifInterface;
import java.util.ArrayList;
import java.util.List;
import javax.crypto.Cipher;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.android.codec.binary.Base64;
import org.apache.commons.android.codec.language.Soundex;

public class b {
    private static final String a = a(a());
    private static final String b = new String(new char[]{&apos;A&apos;, &apos;E&apos;, &apos;S&apos;});

    public static String a(String str, String str2, byte[] bArr) throws Exception {
        byte[] a = a(str);
        Cipher instance = Cipher.getInstance(a);
        instance.init(2, new SecretKeySpec(str2.getBytes(), b), new GCMParameterSpec(128, bArr));
        return new String(instance.doFinal(a));
    }

    private static String a(List&lt;String&gt; list) {
        StringBuffer stringBuffer = new StringBuffer();
        for (String append : list) {
            stringBuffer.append(append);
        }
        return stringBuffer.toString().replace(new String(new char[]{Soundex.SILENT_MARKER}), &quot;&quot;);
    }

    private static String a(byte[] bArr) {
        return Base64.encodeBase64String(bArr);
    }

    private static List&lt;String&gt; a() {
        ArrayList arrayList = new ArrayList();
        arrayList.add(ExifInterface.GPS_MEASUREMENT_IN_PROGRESS);
        arrayList.add(new String(new char[]{&apos;E&apos;, &apos;S&apos;, &apos;/&apos;}));
        arrayList.add(&quot;-G&quot;);
        arrayList.add(&quot;-C-M/&quot;);
        arrayList.add(new String(new char[]{&apos;N&apos;, &apos;o&apos;, &apos;p&apos;, &apos;a&apos;, Soundex.SILENT_MARKER, &apos;d&apos;, &apos;d&apos;}));
        arrayList.add(&quot;in-g&quot;);
        return arrayList;
    }

    private static byte[] a(String str) {
        return Base64.decodeBase64(str);
    }

    public static String b(String str, String str2, byte[] bArr) throws Exception {
        byte[] bytes = str.getBytes();
        Cipher instance = Cipher.getInstance(a);
        instance.init(1, new SecretKeySpec(str2.getBytes(), b), new GCMParameterSpec(128, bArr));
        return a(instance.doFinal(bytes));
    }
}
"><code>package com.bo.hooked.common.d.d;

<span class="hljs-keyword">import</span> <span class="hljs-title">androidx</span>.<span class="hljs-title">exifinterface</span>.<span class="hljs-title">media</span>.<span class="hljs-title">ExifInterface</span>;
<span class="hljs-keyword">import</span> <span class="hljs-title">java</span>.<span class="hljs-title">util</span>.<span class="hljs-title">ArrayList</span>;
<span class="hljs-keyword">import</span> <span class="hljs-title">java</span>.<span class="hljs-title">util</span>.<span class="hljs-title">List</span>;
<span class="hljs-keyword">import</span> <span class="hljs-title">javax</span>.<span class="hljs-title">crypto</span>.<span class="hljs-title">Cipher</span>;
<span class="hljs-keyword">import</span> <span class="hljs-title">javax</span>.<span class="hljs-title">crypto</span>.<span class="hljs-title">spec</span>.<span class="hljs-title">GCMParameterSpec</span>;
<span class="hljs-keyword">import</span> <span class="hljs-title">javax</span>.<span class="hljs-title">crypto</span>.<span class="hljs-title">spec</span>.<span class="hljs-title">SecretKeySpec</span>;
<span class="hljs-keyword">import</span> <span class="hljs-title">org</span>.<span class="hljs-title">apache</span>.<span class="hljs-title">commons</span>.<span class="hljs-title">android</span>.<span class="hljs-title">codec</span>.<span class="hljs-title">binary</span>.<span class="hljs-title">Base64</span>;
<span class="hljs-keyword">import</span> <span class="hljs-title">org</span>.<span class="hljs-title">apache</span>.<span class="hljs-title">commons</span>.<span class="hljs-title">android</span>.<span class="hljs-title">codec</span>.<span class="hljs-title">language</span>.<span class="hljs-title">Soundex</span>;

<span class="hljs-keyword">public</span> class b {
    <span class="hljs-keyword">private</span> static final String a <span class="hljs-operator">=</span> a(a());
    <span class="hljs-keyword">private</span> static final String b <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> String(<span class="hljs-keyword">new</span> char[]{<span class="hljs-string">'A'</span>, <span class="hljs-string">'E'</span>, <span class="hljs-string">'S'</span>});

    <span class="hljs-keyword">public</span> static String a(String str, String str2, <span class="hljs-keyword">byte</span>[] bArr) throws Exception {
        <span class="hljs-keyword">byte</span>[] a <span class="hljs-operator">=</span> a(str);
        Cipher instance <span class="hljs-operator">=</span> Cipher.getInstance(a);
        instance.init(<span class="hljs-number">2</span>, <span class="hljs-keyword">new</span> SecretKeySpec(str2.getBytes(), b), <span class="hljs-keyword">new</span> GCMParameterSpec(<span class="hljs-number">128</span>, bArr));
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> String(instance.doFinal(a));
    }

    <span class="hljs-keyword">private</span> static String a(List<span class="hljs-operator">&#x3C;</span>String<span class="hljs-operator">></span> list) {
        StringBuffer stringBuffer <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> StringBuffer();
        <span class="hljs-keyword">for</span> (String append : list) {
            stringBuffer.append(append);
        }
        <span class="hljs-keyword">return</span> stringBuffer.toString().replace(<span class="hljs-keyword">new</span> String(<span class="hljs-keyword">new</span> char[]{Soundex.SILENT_MARKER}), <span class="hljs-string">""</span>);
    }

    <span class="hljs-keyword">private</span> static String a(<span class="hljs-keyword">byte</span>[] bArr) {
        <span class="hljs-keyword">return</span> Base64.encodeBase64String(bArr);
    }

    <span class="hljs-keyword">private</span> static List<span class="hljs-operator">&#x3C;</span>String<span class="hljs-operator">></span> a() {
        ArrayList arrayList <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> ArrayList();
        arrayList.add(ExifInterface.GPS_MEASUREMENT_IN_PROGRESS);
        arrayList.add(<span class="hljs-keyword">new</span> String(<span class="hljs-keyword">new</span> char[]{<span class="hljs-string">'E'</span>, <span class="hljs-string">'S'</span>, <span class="hljs-string">'/'</span>}));
        arrayList.add(<span class="hljs-string">"-G"</span>);
        arrayList.add(<span class="hljs-string">"-C-M/"</span>);
        arrayList.add(<span class="hljs-keyword">new</span> String(<span class="hljs-keyword">new</span> char[]{<span class="hljs-string">'N'</span>, <span class="hljs-string">'o'</span>, <span class="hljs-string">'p'</span>, <span class="hljs-string">'a'</span>, Soundex.SILENT_MARKER, <span class="hljs-string">'d'</span>, <span class="hljs-string">'d'</span>}));
        arrayList.add(<span class="hljs-string">"in-g"</span>);
        <span class="hljs-keyword">return</span> arrayList;
    }

    <span class="hljs-keyword">private</span> static <span class="hljs-keyword">byte</span>[] a(String str) {
        <span class="hljs-keyword">return</span> Base64.decodeBase64(str);
    }

    <span class="hljs-keyword">public</span> static String b(String str, String str2, <span class="hljs-keyword">byte</span>[] bArr) throws Exception {
        <span class="hljs-keyword">byte</span>[] <span class="hljs-keyword">bytes</span> <span class="hljs-operator">=</span> str.getBytes();
        Cipher instance <span class="hljs-operator">=</span> Cipher.getInstance(a);
        instance.init(<span class="hljs-number">1</span>, <span class="hljs-keyword">new</span> SecretKeySpec(str2.getBytes(), b), <span class="hljs-keyword">new</span> GCMParameterSpec(<span class="hljs-number">128</span>, bArr));
        <span class="hljs-keyword">return</span> a(instance.doFinal(<span class="hljs-keyword">bytes</span>));
    }
}
</code></pre><p>经过frida hook 和调试，发现用的是AES/GCM/Nopadding，加密和解密用的KEY一致，但是vi有区别，两者区别在于发包时以时间戳为基础生成一个vi,而返回数据解包时用的vi是固定的</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/629636ffd91693ecf33e720e9561fb1355e064cb1a3e2ee7fc712afa7fbf9e53.png" alt="加密算法" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="">加密算法</figcaption></figure><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/fb8f0bc74901ae84bfb47638d2e2518263a381b60afabbc3e7b778b3cee79c68.png" alt="固定KEY值" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="">固定KEY值</figcaption></figure><p>用frida注入代码做了测试，能成功加密解密：</p><pre data-type="codeBlock" text="function RequestBodyEncrypt(currentTimeMillis,data)  {
    var b = Java.use(&quot;com.bo.hooked.common.d.d.b&quot;)
    var a = Java.use(&quot;com.bo.hooked.common.d.g.a&quot;)
    var GCMParameterSpec = Java.use(&quot;javax.crypto.spec.GCMParameterSpec&quot;)
    //var currentTimeMillis = 1669299738910
    var key = a.h()
    var vi = a.a(currentTimeMillis)
    return b.b(data, key, vi)
}

function RequestBodyDecrypt(currentTimeMillis,data)  {
    var b = Java.use(&quot;com.bo.hooked.common.d.d.b&quot;)
    var a = Java.use(&quot;com.bo.hooked.common.d.g.a&quot;)
    var GCMParameterSpec = Java.use(&quot;javax.crypto.spec.GCMParameterSpec&quot;)
    //var currentTimeMillis = 1669299738910
    var key = a.h()
    var vi = a.a(currentTimeMillis)
    return b.a(data, key, vi)
}


function ResponseBodDecrypt(data)  {
    var b = Java.use(&quot;com.bo.hooked.common.d.d.b&quot;)
    var a = Java.use(&quot;com.bo.hooked.common.d.g.a&quot;)
    var GCMParameterSpec = Java.use(&quot;javax.crypto.spec.GCMParameterSpec&quot;)
    var key = a.h()
    var vi = a.d()
    return b.a(data, key, vi)
}

function encodeBase64String(data) {
    return Java.use(&quot;com.bo.hooked.common.d.d.b&quot;).a(data)
}

ResponseBodDecrypt(&quot;h60M054rQgQtxxVjZXwJDDMHFftNihcRgL9EBM0drMqjK2VAdqmhAvZTpIojbqIImLQQ9ac0R0xNUhVd7Y4pHNnV/qK9fkKCCKJ/KhZHgqOyHkY=&quot;)
RequestBodyDecrypt(1669299738910,&quot;XXoGEyU6pa+fo28P2YN5ySJ+Ad9vKi73kuropUlvVsvcNNiNwrLBAA/qhjT6&quot;)
RequestBodyEncrypt(1669299738910,&quot;{\&quot;status\&quot;:\&quot;0\&quot;,\&quot;tapCount\&quot;:\&quot;1\&quot;}&quot;)
"><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">RequestBodyEncrypt</span>(<span class="hljs-params">currentTimeMillis,data</span>)  </span>{
    <span class="hljs-keyword">var</span> b <span class="hljs-operator">=</span> Java.use(<span class="hljs-string">"com.bo.hooked.common.d.d.b"</span>)
    <span class="hljs-keyword">var</span> a <span class="hljs-operator">=</span> Java.use(<span class="hljs-string">"com.bo.hooked.common.d.g.a"</span>)
    <span class="hljs-keyword">var</span> GCMParameterSpec <span class="hljs-operator">=</span> Java.use(<span class="hljs-string">"javax.crypto.spec.GCMParameterSpec"</span>)
    <span class="hljs-comment">//var currentTimeMillis = 1669299738910</span>
    <span class="hljs-keyword">var</span> key <span class="hljs-operator">=</span> a.h()
    <span class="hljs-keyword">var</span> vi <span class="hljs-operator">=</span> a.a(currentTimeMillis)
    <span class="hljs-keyword">return</span> b.b(data, key, vi)
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">RequestBodyDecrypt</span>(<span class="hljs-params">currentTimeMillis,data</span>)  </span>{
    <span class="hljs-keyword">var</span> b <span class="hljs-operator">=</span> Java.use(<span class="hljs-string">"com.bo.hooked.common.d.d.b"</span>)
    <span class="hljs-keyword">var</span> a <span class="hljs-operator">=</span> Java.use(<span class="hljs-string">"com.bo.hooked.common.d.g.a"</span>)
    <span class="hljs-keyword">var</span> GCMParameterSpec <span class="hljs-operator">=</span> Java.use(<span class="hljs-string">"javax.crypto.spec.GCMParameterSpec"</span>)
    <span class="hljs-comment">//var currentTimeMillis = 1669299738910</span>
    <span class="hljs-keyword">var</span> key <span class="hljs-operator">=</span> a.h()
    <span class="hljs-keyword">var</span> vi <span class="hljs-operator">=</span> a.a(currentTimeMillis)
    <span class="hljs-keyword">return</span> b.a(data, key, vi)
}


<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ResponseBodDecrypt</span>(<span class="hljs-params">data</span>)  </span>{
    <span class="hljs-keyword">var</span> b <span class="hljs-operator">=</span> Java.use(<span class="hljs-string">"com.bo.hooked.common.d.d.b"</span>)
    <span class="hljs-keyword">var</span> a <span class="hljs-operator">=</span> Java.use(<span class="hljs-string">"com.bo.hooked.common.d.g.a"</span>)
    <span class="hljs-keyword">var</span> GCMParameterSpec <span class="hljs-operator">=</span> Java.use(<span class="hljs-string">"javax.crypto.spec.GCMParameterSpec"</span>)
    <span class="hljs-keyword">var</span> key <span class="hljs-operator">=</span> a.h()
    <span class="hljs-keyword">var</span> vi <span class="hljs-operator">=</span> a.d()
    <span class="hljs-keyword">return</span> b.a(data, key, vi)
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">encodeBase64String</span>(<span class="hljs-params">data</span>) </span>{
    <span class="hljs-keyword">return</span> Java.use(<span class="hljs-string">"com.bo.hooked.common.d.d.b"</span>).a(data)
}

ResponseBodDecrypt(<span class="hljs-string">"h60M054rQgQtxxVjZXwJDDMHFftNihcRgL9EBM0drMqjK2VAdqmhAvZTpIojbqIImLQQ9ac0R0xNUhVd7Y4pHNnV/qK9fkKCCKJ/KhZHgqOyHkY="</span>)
RequestBodyDecrypt(<span class="hljs-number">1669299738910</span>,<span class="hljs-string">"XXoGEyU6pa+fo28P2YN5ySJ+Ad9vKi73kuropUlvVsvcNNiNwrLBAA/qhjT6"</span>)
RequestBodyEncrypt(<span class="hljs-number">1669299738910</span>,<span class="hljs-string">"{\"status\":\"0\",\"tapCount\":\"1\"}"</span>)
</code></pre><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/7ca3aa190080569818a5bfc70f5ea0e7fd51a3cc4cca000c12a8cffc053c2121.png" alt="成功解码" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="">成功解码</figcaption></figure>]]></content:encoded>
            <author>lovefy@newsletter.paragraph.com (dream)</author>
            <enclosure url="https://storage.googleapis.com/papyrus_images/b02e37144d5727ce2f30ef77b52b22abdf1097d1dae18480386e8d1681a2d3b5.png" length="0" type="image/png"/>
        </item>
    </channel>
</rss>