在实施上述任何一项之前,请参阅Scott Arciszewski的答案。
我希望您对我将要分享的内容非常小心,因为我几乎没有安全知识(很有可能我误用了下面的API),所以我们非常乐意更新此答案在社区的帮助下。
正如@richardtallent在他的回答中提到的那样,Web Crypto API受到支持,因此本示例使用该标准。在撰写本文时,全球浏览器支持达到95.88%。
我将使用Web Crypto API共享一个示例
在继续之前,请注意(从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