提问人:Jmlevick 提问时间:1/22/2011 最后编辑:Stephen OstermillerJmlevick 更新时间:12/8/2022 访问量:154101
如何保护 JavaScript 文件?
How do I protect JavaScript files?
问:
我知道隐藏源代码是不可能的,但是,例如,如果我必须将 JavaScript 文件从我的 CDN 链接到网页,并且我不希望人们知道这个脚本的位置和/或内容,这可能吗?
例如,要从网站链接脚本,我们使用:
<script type="text/javascript" src="http://somedomain.example/scriptxyz.js">
</script>
现在,是否可以向用户隐藏脚本的来源,或者隐藏脚本内容并仍在网页上使用它?
例如,通过将其保存在需要密码才能访问文件的私人 CDN 中,这可行吗?如果没有,什么才能得到我想要的东西?
答:
你唯一能做的就是混淆你的代码,使其更难阅读。无论你做什么,如果你想让 javascript 在他们的浏览器中执行,他们就必须有代码。
据我所知,这是不可能的。
您的浏览器必须能够访问 JS 文件才能执行它们。如果浏览器具有访问权限,则浏览器的用户也具有访问权限。
如果您用密码保护您的 JS 文件,那么浏览器将无法访问它们,从而破坏了首先拥有 JS 的目的。
就在我的脑海中,你可以做这样的事情(如果你可以创建服务器端脚本,听起来你可以):
与其像往常一样加载脚本,不如向 PHP 页面发送 AJAX 请求(它可以是任何东西;我只是自己使用它)。让 PHP 找到文件(可能在服务器的非公共部分),用 打开它,然后以字符串形式返回(读取:)内容。file_get_contents
echo
当此字符串返回到 JavaScript 时,让它创建一个新标记,用您刚刚收到的代码填充它,并将标记附加到页面。(你可能会遇到这个问题; 可能不是你需要的,但你可以尝试。script
innerHTML
innerHTML
如果你经常这样做,你甚至可能想要设置一个接受带有脚本名称的 GET 变量的 PHP 页面,以便您可以使用相同的 PHP 动态抓取不同的脚本。(也许你可以改用 POST,让其他人更难看到你在做什么。我不知道。
编辑:我以为你只是想隐藏脚本的位置。如果您试图隐藏脚本本身,这显然不会有太大帮助。
算了吧,这是行不通的。
无论你尝试什么,它都不会起作用。用户需要做的就是发现你的代码及其位置,即在 firebug 的 net 选项卡中查看,或者使用 fiddler 查看正在发出的请求。
Google Closure 编译器、YUI 压缩器、Minify、/Packer/...等等,是压缩/混淆 JS 代码的选项。但是它们都不能帮助您向用户隐藏代码。
任何有一定知识的人都可以使用 JS Beautifier 等工具轻松解码/反混淆您的代码。你的名字。
所以答案是,你总是可以让你的代码更难阅读/解码,但可以肯定的是没有办法隐藏。
答案简单的好问题:你不能!
JavaScript 是一种客户端编程语言,因此它可以在客户端的机器上运行,因此您实际上无法向客户端隐藏任何内容。 混淆代码是一个很好的解决方案,但这还不够,因为尽管这很难,但有人可以破译您的代码并“窃取”您的脚本。 有几种方法可以使你的代码难以被盗,但正如我所说,没有什么是万无一失的。
在我的脑海中,一个想法是限制从嵌入代码的页面外部访问外部 js 文件。在这种情况下,如果您有
<script type="text/javascript" src="myJs.js"></script>
如果有人尝试在浏览器中访问该文件,则不应授予他任何对脚本源的访问权限。
例如,如果你的页面是用PHP编写的,你可以通过函数包含脚本,让脚本决定它是否安全“以返回它的源代码。
在此示例中,您需要外部 “js” (用 PHP 编写) 文件:myJs.js
include
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 id="erasable" type="text/javascript">
//your code goes here
document.getElementById('erasable').innerHTML = "";
</script>
这些都只是简单的黑客,不能,我怎么强调都不为过:不能,完全保护你的js代码,但它们肯定会惹恼那些试图“窃取”你的代码的人。
更新:
我最近看到了一篇非常有趣的文章,作者是 Patrick Weid,关于如何隐藏你的 js 代码,他揭示了一种不同的方法:你可以将源代码编码成图像!当然,这也不是万无一失的,但它是您可以围绕代码构建的另一个栅栏。 这种方法背后的想法是,大多数浏览器都可以使用 canvas 元素对图像进行像素操作。由于画布像素由 4 个值 (rgba) 表示,因此每个像素可以有一个 0-255 范围内的值。这意味着您可以在每个像素中存储一个字符(实际上是 ascii 代码)。其余的编码/解码是微不足道的。
评论
我认为唯一的方法是将所需的数据放在服务器上,并且仅允许登录用户根据需要访问数据(您也可以在服务器端进行一些计算)。这不会保护您的 javascript 代码,但会使其在没有服务器端代码的情况下无法操作
正如我之前在回答gion_13的评论中所说(请阅读),你真的不能。不适用于 javascript。
如果您不希望代码在客户端可用(= 无需付出巨大努力即可窃取), 我的建议是使用在服务器端处理的 PHP(ASP、Python、Perl、Ruby、JSP + Java-Servlets),并且只向用户提供计算/代码执行的结果。或者,如果你愿意,甚至可以使用Flash或Java-Applet,它们允许客户端计算/代码执行,但被编译,因此更难反向引擎(因此并非不可能)。
只有我的 2 美分。
我同意这里其他人的看法:在客户端上使用 JS,猫就从袋子里出来了,没有什么是完全万无一失的。
话虽如此;在某些情况下,我这样做是为了给那些想要查看代码的人设置一些障碍。这就是算法的工作方式(大致)
服务器创建 3 个哈希值和加盐值。一个用于当前时间戳,另外两个用于接下来的 2 秒。这些值通过 Ajax 以逗号分隔的字符串形式发送到客户端;从我的PHP模块。在某些情况下,我认为您可以在页面形成时将这些值硬烘焙到 HTML 的脚本部分中,并在哈希使用结束后删除该脚本标签服务器受 CORS 保护并执行所有通常的SERVER_NAME等检查(这不是太大的保护,但至少为脚本小子提供了一些抵抗力)。
此外,如果服务器检查是否确实有经过身份验证的用户的客户端执行此操作,那就太好了
然后,客户端通过 ajax 调用将相同的 3 个哈希值发送回服务器,以获取我需要的实际 JS。服务器根据那里的当前时间戳检查哈希值......这三个值可确保在 3 秒窗口内发送数据,以考虑浏览器和服务器之间的延迟
服务器需要确信其中一个哈希值是 匹配正确;如果是这样,它将把关键的 JS 送回去 给客户。这是一个简单、粗略的“一次性使用密码” 后端不需要任何数据库。
这意味着,自生成第一组哈希以来,任何黑客都只有 3 秒的窗口期来获取实际的 JS 代码。
整个客户端代码可以位于 IIFE 函数中,因此客户端中的某些变量更难从 Inspector 控制台读取
这不是任何深度解决方案:一个坚定的黑客可以注册,获得一个帐户,然后要求服务器生成前三个哈希值;通过做一些技巧来绕过 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 名称为“encoding_script_being_used”,并且随机化脚本选择了一个名为 MD10 的编码脚本,尽量不要使用 MD10 作为 cookie 的值,而是使用“encoding_script4567656”只是为了防止猜测),然后在创建 cookie 后,另一个脚本将检查名为“encoding_script_being_used”的 cookie 并获取值,然后它将确定正在使用的编码脚本。
现在,在编码脚本之间随机化的原因是,服务器端语言将随机化使用哪个脚本来解码您的javascript.js,然后创建一个会话或 cookie 以了解使用了哪些编码脚本 然后服务器端语言也会对你的 JavaScript .js进行编码,并将其作为 cookie 放置
所以现在让我用一个例子
来总结一下,PHP在编码脚本列表之间随机化并加密javascript.js然后创建一个cookie,告诉客户端语言使用了哪种编码脚本,然后客户端语言解码javascript.js cookie(显然是编码的)
所以人们不能窃取你的代码
但我不会建议这样做,因为
- 这是一个漫长的过程
- 压力太大了
使用我认为有帮助的 NWJS 它可以编译为 bin,然后您可以使用它来制作 Win、Mac 和 Linux 应用程序
评论
如果您不想公开算法中最合理的部分,此方法部分有效。
创建 WebAssembly 模块 (.wasm),导入它们,并只公开你的 JS,等等......工作流。通过这种方式,算法得到了保护,因为将汇编代码恢复为更易于人类阅读的格式是极其困难的。
在生成了 wasm 模块并导入了相应的代码后,您可以像往常一样使用您的代码:
<body id="wasm-example">
<script type="module">
import init from "./pkg/glue_code.js";
init().then(() => {
console.log("WASM Loaded");
});
</script>
</body>
评论