如何保护 JavaScript 文件?

我知道隐藏源代码是不可能的,但是,举例来说,如果我必须将一个 JavaScript 文件从我的 CDN 链接到一个网页,我不想让人们知道这个脚本的位置和/或内容,这可能吗?

例如,要链接来自网站的脚本,我们使用:

<script type="text/javascript" src="http://somedomain.example/scriptxyz.js">
</script>

现在,是否有可能隐藏脚本来自哪里的用户,或隐藏脚本内容,并仍然在网页上使用它?

例如,将它保存在需要密码才能访问文件的私有 CDN 中,是否可行?如果没有,怎样才能得到我想要的?

149579 次浏览

你唯一可以做的是 混淆视听你的代码,使它更难以阅读。不管你做什么,如果你想要 javascript 在他们的浏览器中执行,他们必须有代码。

据我所知,这是不可能的。

您的浏览器必须能够访问 JS 文件才能执行它们。如果浏览器有访问权限,那么浏览器的用户也有访问权限。

如果您使用密码保护您的 JS 文件,那么浏览器将无法访问它们,从而违背了首先使用 JS 的初衷。

你可以这样做(如果你可以创建服务器端脚本,听起来你是可以的) :

与其像往常一样加载脚本,不如向 PHP 页面发送一个 AJAX 请求(它可以是任何东西; 我只是自己使用它)。让 PHP 定位文件(可能在服务器的非公共部分) ,用 file_get_contents打开它,并以字符串形式返回(读取: echo)内容。

当这个字符串返回到 JavaScript 时,让它创建一个新的 script标记,用您刚刚收到的代码填充它的 innerHTML,并将标记附加到页面。(您的 也许吧在这方面有问题; innerHTML可能不是您需要的,但是您可以进行试验。)

如果经常这样做,您甚至可能希望设置一个 PHP 页面,该页面接受带有脚本名称的 GET 变量,这样您就可以使用相同的 PHP 动态抓取不同的脚本。(也许你可以改用 POST,让别人更难看到你在做什么。我不知道。)

编辑: 我以为你只是想隐藏脚本的 位置。如果您试图隐藏脚本本身,那么这显然不会有多大帮助。

算了吧,这是不可能的。

无论你怎么尝试都不会成功的。所有用户需要做的是发现您的代码和它的位置是在网络选项卡中的 纵火犯或使用 小提琴手查看什么请求正在发出。

Google Closure Compiler YUI 压缩机缩小帕克... ... 等等,都是压缩/混淆 JS 代码的选项。但是它们都不能帮助您对用户隐藏代码。

任何有相当知识的人都可以使用 JS 美容师这样的工具轻松地解码或解除代码的混淆。

所以答案是,你总是可以让你的代码难以阅读/解码,但肯定没有办法隐藏。

好问题,简单回答: 你不能

JavaScript 是一种客户端编程语言,因此它可以在客户端机器上工作,所以实际上不能向客户端隐藏任何东西。 混淆您的代码是一个很好的解决方案,但这还不够,因为尽管这很困难,但有人可能会破译您的代码并“窃取”您的脚本。 有几种方法可以让你的代码很难被窃取,但正如我所说,没有什么是防弹的。

我首先想到的一个想法是限制从嵌入代码的页面之外访问外部 js 文件。这样的话,如果你有的话

<script type="text/javascript" src="myJs.js"></script>

如果有人试图在浏览器中访问 myJs.js文件,则不应授予他任何访问脚本源代码的权限。 例如,如果您的页面是用 PHP 编写的,您可以通过 include函数包含该脚本,并让该脚本决定它是否是 安全”以返回其源代码。 在本例中,您将需要外部的“ js”(用 PHP 编写)文件 myJs.php:

<?php
$URL = $_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
if ($URL != "my-domain.example/my-page.php")
die("/\*sry, no acces rights\*/");
?>
// your obfuscated script goes here

这将包括在你的主页 my-page.php:

<script type="text/javascript">
<?php include "myJs.php"; ?>;
</script>

这样,只有浏览器可以看到 js 文件的内容。

另一个有趣的想法是,在脚本的末尾,删除 dom script 元素的内容,这样在浏览器评估代码之后,代码就会消失:

<script id="erasable" type="text/javascript">
//your code goes here
document.getElementById('erasable').innerHTML = "";
</script>

这些都只是简单的黑客技术,不能,我不能强调这一点: 不能,完全保护你的 js 代码,但是他们肯定会激怒那些试图“窃取”你的代码的人。

更新:

我最近看到了 Patrick Weid写的关于如何隐藏 js 代码的 一篇非常有趣的文章,他揭示了一种不同的方法: 您可以将源代码编码到一个图像中!当然,这也不是万无一失的,但它是另一个可以围绕代码构建的 篱笆。 这种方法背后的想法是,大多数浏览器可以使用画布元素对图像进行像素操作。由于画布像素由4个值(rgba)表示,因此每个像素的值可以在0-255之间。这意味着您可以在每个像素中存储一个字符(实际上是 ascii 代码)。编码/解码的其余部分很简单。

我认为唯一的方法是将所需的数据放在服务器上,并且只允许登录用户根据需要访问数据(您也可以在服务器端进行一些计算)。这不会保护您的 javascript 代码,但是会使它在没有服务器端代码的情况下不可操作

正如我之前在 gion _ 13的回复中所说的那样(请阅读) ,你真的不能用 javascript。

如果您不希望代码在客户端可用(= 不需要付出很大努力就可以窃取) , 我的建议是使用 PHP (ASP、 Python、 Perl、 Ruby、 JSP + Java-Servlets) ,它是服务器端处理的,只有计算/代码执行的结果才能提供给用户。或者,如果您愿意,甚至可以使用 Flash 或 Java-Applet,它们允许客户端计算/代码执行,但需要进行编译,因此很难进行反向引擎(这并非不可能)。

只有我的两分钱。

我同意这里的每一个人: 对于客户端的 JS,秘密已经暴露,没有什么是完全万无一失的。

尽管如此,在某些情况下,我这样做是为了给那些希望查看代码的人设置一些障碍。这就是算法的工作原理(大致如此)

  1. 服务器创建3个散列值和加盐值。一个用于当前时间戳,另外两个用于接下来2秒中的每一个。这些值通过 Ajax 以逗号分隔的字符串形式发送到客户机; 这些值来自我的 PHP 模块。在某些情况下,我认为你可以硬烤这些值到 HTML 的脚本部分时,页面形成,并删除该脚本标签一旦哈希使用结束服务器是 CORS 保护,并做所有通常的 SERVER _ NAME 等检查(这不是很大的保护,但至少提供了一些抵抗脚本 kiddies)。

  2. 另外,如果服务器检查是否确实有一个经过身份验证的用户的客户端正在执行此操作,那将是非常好的

  3. 然后,客户机通过一个 ajax 调用将相同的3个散列值发送回服务器,以获取我需要的实际 JS。服务器根据当前的时间戳检查散列... ... 这三个值确保数据在3秒窗口内发送,以说明浏览器和服务器之间的延迟

  4. 服务器需要确信其中一个哈希是 匹配正确; 如果是这样,它将发送关键的 JS 回来 这是一个简单粗糙的“一次性使用密码” 不需要后端的任何数据库。

  5. 这意味着,任何黑客只有3秒的窗口期,因为生成的第一组哈希到达实际的 JS 代码。

  6. 整个客户端代码可以在一个 IIFE 函数中,因此客户端内部的一些变量更难从检查器控制台读取

    这并不是什么深入的解决方案: 一个坚定的黑客可以注册,获得一个帐户,然后要求服务器生成前三个哈希; 通过使用技巧绕过 Ajax 和 CORS; 然后让客户机执行第二个调用以获得实际的代码——但这是一个合理的工作量。

此外,如果服务器使用的 Salt 是基于登录凭证的,那么服务器可能能够检测到那个试图检索敏感 JS 的用户是谁(在检索敏感 JS 之后,服务器需要对用户的行为做一些额外的工作,并且如果那个人,比如说,没有做一些预期的其他活动,那么就阻止这个人)

一个旧的,粗糙的版本是这里做了一个黑客马拉松: http://planwithin.com/demo/tadr.html这将不工作的情况下,服务器检测到太多的延迟,它超过了3秒的窗口期

您还可以为 application/JavaScript 设置一个 mime 类型,以作为 PHP 运行。NET,Java,或者任何你正在使用的语言。我在过去已经为动态 CSS 文件这样做了。

我知道现在不是回答这个问题的时候,但是我刚刚想到了一些事情

我知道可能压力很大,但至少 也许吧还能用

现在的诀窍是 创造有很多服务器端的编码脚本,它们必须是可解码的(例如一个脚本,用数字代替所有的元音,并在每个辅音上加上字母‘ a’,这样单词‘ bat’就变成了 ba1ta) ,然后创建一个脚本,在编码脚本之间随机化,并创建一个使用编码脚本名称的 cookie(快速提示: 不要使用 Cookie 的编码脚本的实际名称,例如,如果我们的 Cookie 的名称是‘ coding _ script _ being _ used’,并且随机化脚本选择了一个名为 MD10的编码脚本,为了防止猜测,不要使用 MD10作为 Cookie 的值,而应该使用‘ coding _ script4567656’)然后,在创建了 cookie 之后,另一个脚本将检查名为“ coding _ script _ being _ used”的 cookie 并获取值,然后它将确定正在使用哪个编码脚本。

现在随机化编码脚本的原因是服务器端语言将随机化用于解码 javascript.js 的脚本,然后创建一个会话或 cookie 来知道使用了哪些编码脚本 然后服务器端语言也会对 javascript. js 进行编码,并将其设置为 < strong > cookie






现在让我用一个例子来总结一下

PHP 在一系列编码脚本之间随机选择,然后加密 javascript.js,然后创建一个 cookie,告诉客户端语言使用了哪种编码脚本,然后客户端语言解码 javascript.js cookie (显然是编码的)

这样别人就不能偷你的代码了

但我不建议这么做,因为

  1. 这是一个漫长的过程
  2. 压力太大了

使用 nwjs 我认为很有帮助,它可以编译成 bin,然后你可以使用它来制作 win,mac 和 linux 应用程序

如果您不想公开算法中最有意义的部分,则此方法可以部分工作。

创建 WebAssembly 模块(。) ,导入它们,并只暴露您的 JS,等等。.工作流程。通过这种方式,算法得到了保护,因为将汇编代码恢复为更易于阅读的格式是极其困难的。

在生成 wasm 模块并导入正确性之后,您可以像平常一样使用您的代码:

<body id="wasm-example">
<script type="module">
import init from "./pkg/glue_code.js";
init().then(() => {
console.log("WASM Loaded");
});
</script>
</body>