节点加密sha256不使用空格

时间:2018-06-14 06:22:18

标签: node.js cryptography content-security-policy jsdom

我做错了什么还是这个错误?

使用时

var checkSum = crypto.createHash("sha256").update(scriptInnerHTML, "utf-8").digest("base64")

为此脚本标记生成sha256:

<script>

    console.warn("works");
    var some code ... 
</script>

在Content-Security-Policy中使用它,如下所示:

<meta http-equiv="Content-Security-Policy" content="script-src 'sha256-8O+YTKIDgMhMvSanTZx1Om5XY2ERB+kIxN8AcO2r6Ok='">

事情可以正常运作,但是除了没有警告日志之外,这个相同,不起作用。注意代码之前的几行新行和一个标签。

<script>


    var some code ... 
</script>

如果之后有文本,Node似乎会以不同方式解释制表符(或更确切地说是换行符+制表符)。怪异!

在Safari和Chrome中都进行了测试,因此不应该是浏览器问题。

更新: 我当然会为每个输入重新生成哈希值。

示例:

(脚本标签位于底部)

工作哈希('sha256-5 ++ 3ItSu + 9maCZiuuXH60RG7EugmibMmhxhwpsynAn0 ='):http://aggressive.se/test/works.html

不工作哈希('sha256-hIRDHGUSaEmjNiVhNabY + 8l4GNQdj / PXD4XHA21gdRM ='):http://aggressive.se/test/fail.html

解决: 问题是由于JSDom中的serialize()函数,我用它来生成节点中的HTML。在计算哈希值之后调用dom.serialize(),它删除了一个不必要的选项卡,它改变了源代码(以一种难以注意的方式)。

但是你知道,问题不在于节点和加密模块。 (希望有人为此使用)

1 个答案:

答案 0 :(得分:1)

我不确定你是如何获得scriptInnerHTML变量的,但是如果我在innerHTML示例中访问感兴趣的脚本的fail.html属性,我会得到这个hexdump:

00000000  0a 0a 0a 09 76 61 72 20  6c 61 79 6f 75 74 20 3d  |....var layout =|
00000010  20 6e 65 77 20 41 67 67  72 65 73 73 69 76 65 4c  | new AggressiveL|
00000020  61 79 6f 75 74 28 29 3b  0a 09 41 67 67 72 65 73  |ayout();..Aggres|
00000030  73 69 76 65 4c 61 79 6f  75 74 2e 70 72 6f 74 6f  |siveLayout.proto|
00000040  74 79 70 65 2e 73 65 74  75 70 46 75 6e 63 74 69  |type.setupFuncti|
00000050  6f 6e 20 3d 20 66 75 6e  63 74 69 6f 6e 28 29 0a  |on = function().|
00000060  09 7b 0a 09 09 76 61 72  20 65 6c 65 6d 65 6e 74  |.{...var element|
00000070  20 3d 20 64 6f 63 75 6d  65 6e 74 2e 63 72 65 61  | = document.crea|
00000080  74 65 45 6c 65 6d 65 6e  74 28 22 64 69 76 22 29  |teElement("div")|
00000090  3b 0a 09 09 65 6c 65 6d  65 6e 74 2e 69 6e 6e 65  |;...element.inne|
000000a0  72 48 54 4d 4c 20 3d 20  22 49 74 20 77 6f 72 6b  |rHTML = "It work|
000000b0  73 22 3b 0a 09 09 74 68  69 73 2e 65 6c 65 6d 65  |s";...this.eleme|
000000c0  6e 74 73 2e 72 6f 6f 74  45 6c 65 6d 65 6e 74 2e  |nts.rootElement.|
000000d0  61 70 70 65 6e 64 43 68  69 6c 64 28 65 6c 65 6d  |appendChild(elem|
000000e0  65 6e 74 29 0a 09 7d 0a                           |ent)..}.|

其对应的哈希是bR9Os+NBLWNZ3/wFVRhBilP05u9OeSj0ABRo+T8QF+g=。如果我在html文件中使用此哈希,它似乎工作...

JSDOM的示例:

const fs = require('fs');
const crypto = require('crypto');
const { JSDOM } = require('jsdom');

const dom = new JSDOM(fs.readFileSync('./fail.html'));
const data = dom.window.document.querySelector('head > script:last-child').innerHTML;

console.log(crypto.createHash('sha256').update(data, 'utf-8').digest('base64'));
//bR9Os+NBLWNZ3/wFVRhBilP05u9OeSj0ABRo+T8QF+g=