java爬虫js加密_Java爬虫(四)-- Java 调用 JS 函数 模拟页面 JS 密码加密(附几个知识点)...

本文详细介绍了如何使用Java的ScriptEngine模拟网页JS密码加密过程,通过调试定位加密JS代码,借助Nashorn JavaScript引擎执行JS文件并调用函数,实现了在Java中复现加密算法。
摘要由CSDN通过智能技术生成

前言

前面一章讲的是模拟登录,留了一个模拟密码加密还没讲。

因为这一过程的调试探索还是蛮多内容的,我更倾向于记录自己整个探索的过程,而不是把工具拿出来讲一下用法,所以单独拿一章来讲。

调试过程

首先,既然要模拟js的加密过程,当然是要调试前端代码,从定位到起加密作用的js代码上面。

F12浏览器调试时,source目录下可以看到当前的浏览器的一些静态文件,包括页面,css,js等文件,一开始先定位到点击登录按钮之后,肯定会执行的js代码,然后在那个上面打断点。

像我要爬取的网站,会根据你所使用的浏览器使用不同的加密算法,所以要通过调试,知道它到底是怎么加密的。

打了断点之后,我成功找到了加密的代码,

677aef0592cb2ca6068877a11801b544.png

可以看到起加密作用的就是ciper.Enrypt()方法。把鼠标放在上面,点击如图所示出现的悬浮小窗里面的Enrypt(a,b),就跳到对应的js文件里面。

这里就有一个很神奇的东西了,跳到的js文件并不在我source目录中,而是一个VM+"一串数字"的js中。

查询了去Stack Overflow上面查了之后,看到了如下回答

[VM] (scriptId) has no special meaning. It's a dummy name to help us to distinguish code which are not directly tied to a file name, such as code created using eval and friends.

VM是虚拟机(Virtual Machine)的缩写,后面的数字是代码的编号ID,主要是为了区别原网页的js与其他来源的js(比如eval创建的, ajax获取的等)

也就是说这个加密的js是动态加载出来的。

定位到js之后,接下去就是怎么模拟了。

ScriptEngine

加密算法,可以说是非常复杂,所以不可能用java语言去模拟。就想着能不能在jvm上运行js的文件,这么一搜,还真有。

java中的javax.script,它开始存在于JDK1.6,它可以解析通用的表达式,如三目,还可以利用js函数语法,创造一个就像java的函数一样存在于内存中随时可以被调用的函数,更可以将js中的对象直接转换成java对象。

到了java8 之后 叫做 Nashorn JavaScript 引擎。扩展了很多功能。

只不过这里面我们只使用它加载js文件,调用js中函数的功能,其他功能有兴趣的可以自己去了解一下。

先介绍下基础用法

在Java中直接调用js代码

import javax.script.ScriptEngine;

import javax.script.ScriptEngineManager;

import javax.script.ScriptException;

/** * 直接调用js代码 */

public class ScriptEngineTest {

public static void main(String[] args) {

ScriptEngineManager manager = new ScriptEngineManager();

ScriptEngine engine = manager.getEngineByName("javascript");

try {

engine.eval("var a=3; var b=4;print (a+b);");

} catch (ScriptException e) {

e.printStackTrace();

}

}

}

Java中调用js文件中的function,传入调用参数,并获取返回值

// demo.js

function count(a, b) {

c = a * b;

return c;

}

在Java代码中读取js文件,并参数两个参数,然后回去返回值

import java.io.FileReader;

import javax.script.Invocable;

import javax.script.ScriptEngine;

import javax.script.ScriptEngineManager;

public class ScriptEngineTest {

public static void main(String[] args) throws Exception {

ScriptEngineManager manager = new ScriptEngineManager();

ScriptEngine engine = manager.getEngineByName("javascript");

String jsFileName = "demo.js";

// 读取js文件

FileReader reader = new FileReader(jsFileName);

// 执行指定脚本

engine.eval(reader);

if(engine instanceof Invocable) {

Invocable invoke = (Invocable)engine;

// 调用count方法,并传入两个参数

Double c = (Double)invoke.invokeFunction("merge", 2, 3);

System.out.println("c = " + c);

}

reader.close();

}

}

实战

了解了前面的基础知识和简单热身后,我这个问题就简单了。我浏览器上调试显示的js拷贝出来新建了一个js文件,放到resource目录下,用ScriptEngine去加载,把明文密码和公钥当做变量传进去调用js 中的function,这就好像是黑箱,我不需要知道里面的加密互相调用是怎么样。

这里有一个坑注意一下:ScriptEngine执行js代码或者js文件的时候,被调用的代码中如果引用了浏览器中存在的对象,就会报错。比如alert,navigator之类的。

ReferenceError: "xxx" is not defined

原因显而易见,这个对象在你的脚本引擎中没有定义。

我在解决这个问题的时候,先是看了一下有哪些对象,这些对象具体起了什么作用。

看了之后发现,都是起着兼容性的作用,不同浏览器版本就会用不同的变量值或者说调用不同的加密方法。我就直接删去了里面兼容性判断部分的代码,给一些变量值指定了定值。最后就起到了同样的效果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值