前言
對java逆向感興趣的盆友可以關(guān)注我以前的文章,有圖片驗證碼識別、AES、SHA256等各種加密的java實現(xiàn),不定時更新常用算法和加密,歡迎一起交流討論!
在日常逆向中,一些前端的加密代碼用java復(fù)現(xiàn)出來比較難,所以經(jīng)常需要調(diào)用js文件來實現(xiàn)加密操作,接下來將介紹兩種常用調(diào)用js的思路,第一種適用于普通js文件,第二種則適用于比較新的V8引擎。在實現(xiàn)的過程中,也會展示可能遇到的問題以及解決辦法,廢話不多話,正文開始!
方法一
本方法用的是jdk自帶的ScriptEngine
來實現(xiàn),大概流程是:加載引擎->綁定環(huán)境->預(yù)編譯js文件->調(diào)用文件內(nèi)方法,具體實現(xiàn)代碼:
import javax.script.*;
import java.io.InputStreamReader;
//因為js文件讀取一次就行,因此用靜態(tài)代碼塊來讀取
private static ScriptEngine engine;
static {
try {
ScriptEngineManager manager = new ScriptEngineManager();
engine = manager.getEngineByName("javascript");
Bindings engineScope = engine.getBindings(ScriptContext.ENGINE_SCOPE);
engineScope.put("window", engineScope);
engineScope.put("navigator", engineScope);
InputStreamReader jsencryptFileReader = new InputStreamReader(EncJs.class.getClassLoader().getResourceAsStream("enc.js"));
engine.eval(jsencryptFileReader);
jsencryptFileReader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
讀取完js后,就可以使用js引擎來直接用invokeFunction
方法來調(diào)用文件內(nèi)函數(shù),代碼如下
public static String enc(String data, String key) {
Invocable invoke = (Invocable) engine;
try {
String result = (String) invoke.invokeFunction("Enc", data, key);
return result.toUpperCase();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
在上邊代碼invoke.invokeFunction("Enc", data, key)
中,Enc
為js文件內(nèi)的函數(shù)名,data
和key
是需要方法需要傳遞的參數(shù),如果方法只有一個參數(shù),則傳入一個,如果是多個參數(shù),則按順序排列在后邊即可。
上邊代碼在執(zhí)行普通js時比較方便使用,但是如果是比較新的開發(fā)版本,有些語法會不支持,像lambda表達(dá)式等,如下圖:
此處再介紹一種方法,使用的是V8引擎,可以支持最新語法
方法二
使用到的maven依賴,以下依賴根據(jù)自己環(huán)境任選其一即可。
<!-- linux系統(tǒng) -->
<dependency>
<groupId>com.eclipsesource.j2v8</groupId>
<artifactId>j2v8_linux_x86_64</artifactId>
<version>3.1.6</version>
</dependency>
<!-- mac系統(tǒng) -->
<dependency>
<groupId>com.eclipsesource.j2v8</groupId>
<artifactId>j2v8_macosx_x86_64</artifactId>
<version>4.6.0</version>
</dependency>
<!-- windows系統(tǒng) -->
<dependency>
<groupId>com.eclipsesource.j2v8</groupId>
<artifactId>j2v8_win32_x86_64</artifactId>
<version>4.6.0</version>
</dependency>
這個的實現(xiàn)流程和上邊稍微有些不同,也是:預(yù)讀取js文件>加載引擎->編譯js文件->調(diào)用文件內(nèi)方法,具體實現(xiàn)代碼如下:
import com.eclipsesource.v8.V8;
import org.apache.commons.io.IOUtils;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
public class V8JSUtils {
private static String fileStr;
static {
try {
fileStr = IOUtils.toString(V8JSUtils.class.getClassLoader().getResourceAsStream("enc.js"), StandardCharsets.UTF_8);
} catch (IOException e) {
e.printStackTrace();
}
}
public static String dec(String data, String key) {
V8 runtime = V8.createV8Runtime();
try {
runtime.executeVoidScript(fileStr);
return (String) runtime.executeJSFunction("Dec", data, key);
} catch (Exception e) {
e.printStackTrace();
} finally {
runtime.release();
}
return null;
}
}
代碼寫完了,調(diào)用一下結(jié)果還是遇到了錯誤
這個錯誤的大概意思就是:嚴(yán)格模式外不能使用let,const之類的es6的命令,也就是說版本太低了,怎么辦,更新版本?no no no,找到JS文件出錯的代碼位置,在方法前加上一句:'use strict';
注意!引號不能省略,必須全部復(fù)制,如圖文章來源:http://www.zghlxwxcb.cn/news/detail-695907.html
現(xiàn)在再運行就正常了。文章來源地址http://www.zghlxwxcb.cn/news/detail-695907.html
到了這里,關(guān)于java調(diào)用js文件的兩種方法(支持V8引擎)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!