在实施任何这些之前,请参阅Scott Arciszewski's answer。
我希望您对我将要分享的内容非常小心,因为我几乎没有安全知识(我很可能误用了下面的 API),所以我非常欢迎在社区的帮助下更新此答案。
正如@richardtallent 在他的answer 中提到的那样,支持Web Crypto API,所以这个例子使用了标准。在撰写本文时,有一个95.88% of global browser support。
我将分享一个使用 Web Crypto API 的示例
在我们继续之前,请注意 (Quoting from MDN):
此 API 提供了许多低级加密原语。 很容易被误用,而且所涉及的陷阱可能非常微妙。
即使假设您正确使用基本的加密功能,安全密钥管理和整体安全系统设计很难做到正确,而且通常是专业安全专家的领域。
安全系统设计和实施中的错误会使系统的安全性完全失效。
如果您不确定自己在做什么,您可能不应该使用此 API。
我非常尊重安全性,我什至将 MDN 的其他部分加粗... 您已被警告
现在,到实际的例子......
JSFiddle:
在这里找到:https://jsfiddle.net/superjose/rm4e0gqa/5/
注意:
注意await 关键字的使用。在async 函数中使用它或使用.then() 和.catch()。
生成密钥:
// https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey
// https://developer.mozilla.org/en-US/docs/Web/API/RsaHashedKeyGenParams
// https://github.com/diafygi/webcrypto-examples#rsa-oaep---generatekey
const stringToEncrypt = 'https://localhost:3001';
// https://github.com/diafygi/webcrypto-examples#rsa-oaep---generatekey
// The resultant publicKey will be used to encrypt
// and the privateKey will be used to decrypt.
// Note: This will generate new keys each time, you must store both of them in order for
// you to keep encrypting and decrypting.
//
// I warn you that storing them in the localStorage may be a bad idea, and it gets out of the scope
// of this post.
const key = await crypto.subtle.generateKey({
name: 'RSA-OAEP',
modulusLength: 4096,
publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
hash: {name: 'SHA-512'},
}, true,
// This depends a lot on the algorithm used
// Go to https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto
// and scroll down to see the table. Since we're using RSA-OAEP we have encrypt and decrypt available
['encrypt', 'decrypt']);
// key will yield a key.publicKey and key.privateKey property.
加密:
const encryptedUri = await crypto.subtle.encrypt({
name: 'RSA-OAEP'
}, key.publicKey, stringToArrayBuffer(stringToEncrypt))
console.log('The encrypted string is', encryptedUri);
解密
const msg = await crypto.subtle.decrypt({
name: 'RSA-OAEP',
}, key.privateKey, encryptedUri);
console.log(`Derypted Uri is ${arrayBufferToString(msg)}`)
从 String 来回转换 ArrayBuffer(在 TypeScript 中完成):
private arrayBufferToString(buff: ArrayBuffer) {
return String.fromCharCode.apply(null, new Uint16Array(buff) as unknown as number[]);
}
private stringToArrayBuffer(str: string) {
const buff = new ArrayBuffer(str.length*2) // Because there are 2 bytes for each char.
const buffView = new Uint16Array(buff);
for(let i = 0, strLen = str.length; i < strLen; i++) {
buffView[i] = str.charCodeAt(i);
}
return buff;
}
您可以在此处找到更多示例(我不是所有者):
//https://github.com/diafygi/webcrypto-examples