如果您出于安全原因尝试创建页面稍后加载的代码无法找到的功能,您应该知道默认情况下 window 的属性是可枚举的,并且 JavaScript 的 PRNG 不是加密强的。
@MikeSamuel 这正是我想要做的。
如果你有一个加密的强随机源,那么你可以使用 lock&key 方法来创建一个只能由知道秘密的人调用的函数。
例如,
(function () {
// Multiple calls to a secure source of randomness could get you more entropy than 64B.
var key = Math.random() + '/' + Math.random() + '/' + Math.random();
var sensitiveFunction = function () { alert("Don't leak me"); }
var slice = [].slice;
function lock(f) {
var g = f;
f = null; // arguments is widgy and leaky in non-strict mode.
return function (unlocker, var_args) {
if (key !== unlocker) { throw new Error(); }
return g.call(this, slice.apply(arguments, 1));
};
}
myGlobal = lock(sensitiveFunction);
})();
它使用秘密将一个函数包装在一个toString()
不返回敏感代码的函数中,并且只能由可以读取的代码调用var key
。
Math.random() 在密码学上是安全的吗?讨论了Math.random
JavaScript 中强随机数的一些替代方案,但我对其中任何一个都没有个人经验。
除非您可以摆脱对需要它的代码的封闭,否则这实际上没有用key
,因此您需要有一个与该代码的安全通信通道。您可能还希望有任何定义它的脚本遍历<script>
元素并从 DOM 中删除它们的文本内容,以便无法以这种方式读取敏感函数的主体。
我相信像waterken这样的框架使用 URL 片段来为 Web 应用程序植入秘密,然后在页面中使用类似的技术来防止它们窥探代码。
请注意,使具有不可预测名称的属性不可枚举并不能保护它们。
在 EcmaScript 5 中,getOwnPropertyNames
不尊重可枚举性。获得真正不可枚举的属性的唯一标准化方法是使用弱映射和密切持有的对象令牌,并且必须等待 EcmaScript 6 成为实际规范,尽管浏览器供应商正在推测性地实现大量 ES6。