在实施任何这些之前,请参阅Scott Arciszewski 的回答。
我希望您对我将要分享的内容非常小心,因为我几乎没有安全知识(我很可能滥用了下面的 API),所以我非常欢迎更新这个答案在社区的帮助下。
正如@richardtallent 在他的回答中提到的那样,支持 Web Crypto API,所以这个例子使用了标准。在撰写本文时,全球浏览器支持率为 95.88%。
我将分享一个使用 Web Crypto API 的示例
在我们继续之前,请注意(引用自 MDN):
此 API 提供了许多低级加密原语。很容易误用它们,所涉及的陷阱可能非常微妙。
即使假设您正确使用了基本的加密功能,安全密钥管理和整体安全系统设计也很难做到正确,并且通常是专业安全专家的领域。
安全系统设计和实施中的错误会使系统的安全性完全失效。
如果你不确定你知道你在做什么,你可能不应该使用这个 API。
我非常尊重安全性,我什至加粗了 MDN 的其他部分......你已经被警告
现在,到实际的例子......
JSF中:
在这里找到:https ://jsfiddle.net/superjose/rm4e0gqa/5/
笔记:
注意await
关键字的使用。async
在函数中使用它或使用.then()
and .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