最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to create a hash using Web Crypto API? - Stack Overflow

programmeradmin2浏览0评论

I'm trying to create SHA-1 hash on the client-side. I'm trying to do this with Web Crypto API but when I'm paring the output to what various online tools give me, the result is pletely different. I think the problem is in ArrayBuffer to Hex conversion. Here is my code:

function generateHash() {
            var value = "mypassword";
            var crypto = window.crypto;
            var buffer = new ArrayBuffer(value);
            var hash_bytes = crypto.subtle.digest("SHA-1", buffer);
            hash_bytes.then(value => document.write([...new Uint8Array(value)].map(x => x.toString(16).padStart(2, '0')).join('')));
        }

Output of document.write should be:

91dfd9ddb4198affc5c194cd8ce6d338fde470e2

But it's not, I get a pletely different hash of different length (should be 40). Could I have some advise on the problem? Thanks.

I'm trying to create SHA-1 hash on the client-side. I'm trying to do this with Web Crypto API but when I'm paring the output to what various online tools give me, the result is pletely different. I think the problem is in ArrayBuffer to Hex conversion. Here is my code:

function generateHash() {
            var value = "mypassword";
            var crypto = window.crypto;
            var buffer = new ArrayBuffer(value);
            var hash_bytes = crypto.subtle.digest("SHA-1", buffer);
            hash_bytes.then(value => document.write([...new Uint8Array(value)].map(x => x.toString(16).padStart(2, '0')).join('')));
        }

Output of document.write should be:

91dfd9ddb4198affc5c194cd8ce6d338fde470e2

But it's not, I get a pletely different hash of different length (should be 40). Could I have some advise on the problem? Thanks.

Share Improve this question asked Jun 26, 2021 at 10:41 Mr. EngineerMr. Engineer 3752 gold badges11 silver badges34 bronze badges 1
  • Any advise guys? – Mr. Engineer Commented Jun 26, 2021 at 11:11
Add a ment  | 

3 Answers 3

Reset to default 6

This is a basic function to generate a SHA-1 hex string digest for any input string:

async function digest(message, algo = 'SHA-1') {
  return Array.from(
    new Uint8Array(
      await crypto.subtle.digest(algo, new TextEncoder().encode(message))
    ),
    (byte) => byte.toString(16).padStart(2, '0')
  ).join('');
}

The problem seems to be more the input conversion from a string to an ArrayBuffer. E.g. with str2ab() the code works:

generateHash();

function generateHash() {
    var value = "mypassword";
    var crypto = window.crypto;
    var buffer = str2ab(value); // Fix
    var hash_bytes = crypto.subtle.digest("SHA-1", buffer);
    hash_bytes.then(value => document.write([...new Uint8Array(value)].map(x => x.toString(16).padStart(2, '0')).join('')));
}

// https://stackoverflow./a/11058858
function str2ab(str) {
    const buf = new ArrayBuffer(str.length);
    const bufView = new Uint8Array(buf);
    for (let i = 0, strLen = str.length; i < strLen; i++) {
        bufView[i] = str.charCodeAt(i);
    }
    return buf;
}

with the expected output:

91dfd9ddb4198affc5c194cd8ce6d338fde470e2

Using the debugger, it looks like var buffer = new ArrayBuffer(value); results in buffer being an empty ArrayBuffer. The text string stored in value must be utf-8 encoded in order to be correctly converted to bytes, which can then by passed as an input to the crypto.subtle.digest() function.

Try changing:

var buffer = new ArrayBuffer(value);

to:

var buffer = new TextEncoder("utf-8").encode(value);

This creates a Uint8Array (as expected by crypto.subtle.digest()) consisting of the bytes resulting from utf-8 encoding the text string in 'value'. This should solve the problem and produce the result that you are expecting.

发布评论

评论列表(0)

  1. 暂无评论