jer*_*ahs 126 javascript encryption
我有兴趣构建一个供个人使用的小应用程序,它将使用JavaScript在客户端加密和解密信息.加密信息将存储在服务器上的数据库中,但不会存储在解密版本中.
它不一定非常安全,但我想使用当前不间断的算法.
理想情况下,我可以做类似的事情
var gibberish = encrypt(string, salt, key);
Run Code Online (Sandbox Code Playgroud)
生成编码的字符串,等等
var sensical = decrypt(gibberish, key);
Run Code Online (Sandbox Code Playgroud)
稍后解码.
到目前为止,我已经看到了这个:http: //bitwiseshiftleft.github.io/sjcl/
我应该看看其他任何图书馆?
Tom*_*rda 142
var encrypted = CryptoJS.AES.encrypt("Message", "Secret Passphrase");
//U2FsdGVkX18ZUVvShFSES21qHsQEqZXMxQ9zgHy+bu0=
var decrypted = CryptoJS.AES.decrypt(encrypted, "Secret Passphrase");
//4d657373616765
document.getElementById("demo1").innerHTML = encrypted;
document.getElementById("demo2").innerHTML = decrypted;
document.getElementById("demo3").innerHTML = decrypted.toString(CryptoJS.enc.Utf8);Run Code Online (Sandbox Code Playgroud)
Full working sample actually is:
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/aes.js"></script>
<br><br>
<label>encrypted</label>
<div id="demo1"></div>
<br>
<label>decrypted</label>
<div id="demo2"></div>
<br>
<label>Actual Message</label>
<div id="demo3"></div>Run Code Online (Sandbox Code Playgroud)
小智 54
它是一个可靠的加密库,具有很多功能.它实现了哈希,HMAC,PBKDF2和密码.在这种情况下,密码就是您所需要的.查看项目主页上的快速启动信息.
您可以使用AES执行某些操作:
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/aes.js"></script>
<script>
var encryptedAES = CryptoJS.AES.encrypt("Message", "My Secret Passphrase");
var decryptedBytes = CryptoJS.AES.decrypt(encryptedAES, "My Secret Passphrase");
var plaintext = decryptedBytes.toString(CryptoJS.enc.Utf8);
</script>
Run Code Online (Sandbox Code Playgroud)
至于安全性,在我写作的那一刻,AES算法被认为是不间断的
编辑:
似乎在线URL已关闭,您可以使用下面给定链接下载的文件进行加密,并将相应文件放在应用程序的根文件夹中.
https://code.google.com/archive/p/crypto-js/downloads
或使用其他CDN,如https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/aes-min.js
Jor*_*lom 26
我创建了一个简单的文本密码/解密工具。不依赖任何外部库。
这些是功能
let cipher = salt => {
let textToChars = text => text.split('').map(c => c.charCodeAt(0))
let byteHex = n => ("0" + Number(n).toString(16)).substr(-2)
let applySaltToChar = code => textToChars(salt).reduce((a,b) => a ^ b, code)
return text => text.split('')
.map(textToChars)
.map(applySaltToChar)
.map(byteHex)
.join('')
}
let decipher = salt => {
let textToChars = text => text.split('').map(c => c.charCodeAt(0))
let saltChars = textToChars(salt)
let applySaltToChar = code => textToChars(salt).reduce((a,b) => a ^ b, code)
return encoded => encoded.match(/.{1,2}/g)
.map(hex => parseInt(hex, 16))
.map(applySaltToChar)
.map(charCode => String.fromCharCode(charCode))
.join('')
}
Run Code Online (Sandbox Code Playgroud)
您可以如下使用它们:
// To create a cipher
let myCipher = cipher('mySecretSalt')
//Then cipher any text:
myCipher('the secret string') // --> "7c606d287b6d6b7a6d7c287b7c7a61666f"
//To decipher, you need to create a decipher and use it:
let myDecipher = decipher('mySecretSalt')
myDecipher("7c606d287b6d6b7a6d7c287b7c7a61666f") // --> 'the secret string'
Run Code Online (Sandbox Code Playgroud)
ric*_*ent 16
现代浏览器现在支持crypto.subtleAPI,它使用以下方法之一提供本机加密和解密功能(异步不少!):AES-CBC,AES-CTR,AES-GCM或RSA-OAEP.
https://www.w3.org/TR/WebCryptoAPI/#dfn-Crypto
Met*_*ron 14
@Jorgeblom 我的男人,这是一个很棒的小型加密库 :D 我有点触动它,因为我不喜欢我必须分配盐并再次调用它,但总的来说,对于我的需求来说绝对是完美的。
const crypt = (salt, text) => {
const textToChars = (text) => text.split("").map((c) => c.charCodeAt(0));
const byteHex = (n) => ("0" + Number(n).toString(16)).substr(-2);
const applySaltToChar = (code) => textToChars(salt).reduce((a, b) => a ^ b, code);
return text
.split("")
.map(textToChars)
.map(applySaltToChar)
.map(byteHex)
.join("");
};
const decrypt = (salt, encoded) => {
const textToChars = (text) => text.split("").map((c) => c.charCodeAt(0));
const applySaltToChar = (code) => textToChars(salt).reduce((a, b) => a ^ b, code);
return encoded
.match(/.{1,2}/g)
.map((hex) => parseInt(hex, 16))
.map(applySaltToChar)
.map((charCode) => String.fromCharCode(charCode))
.join("");
};
Run Code Online (Sandbox Code Playgroud)
你用它
// encrypting
const encrypted_text = crypt("salt", "Hello"); // -> 426f666665
// decrypting
const decrypted_string = decrypt("salt", "426f666665"); // -> Hello
Run Code Online (Sandbox Code Playgroud)
小智 11
crypt.subtle AES-GCM,独立,经过测试:
async function aesGcmEncrypt(plaintext, password)
async function aesGcmDecrypt(ciphertext, password)
Run Code Online (Sandbox Code Playgroud)
https://gist.github.com/chrisveness/43bcda93af9f646d083fad678071b90a
Sco*_*ski 10
利用SJCL,CryptoJS和/或WebCrypto的现有答案不一定是错误的,但是它们并不像您最初怀疑的那样安全。通常,您要使用libsodium。首先,我将解释原因,然后再解释。
简短的答案:为了使您的加密实际上是安全的,这些库希望您做出太多选择,例如块密码模式(CBC,CTR,GCM;如果您不能确定我刚刚列出的三种加密方法中的哪一种是安全的),使用和在什么样的约束,你不应该有这种选择的负担在所有)。
除非您的职位是密码学工程师,否则您就无法安全地实施它。
CryptoJS提供了一些构建基块,希望您知道如何安全地使用它们。它甚至默认为CBC模式(archived)。
WebCrypto是委员会制定的杂烩标准,目的是与密码学工程正交。具体来说,WebCrypto旨在取代Flash,而不是提供安全性。
SJCL的公共API和文档恳求用户使用人类记住的密码来加密数据。如果有的话,这几乎是您在现实世界中想要做的事情。
此外:其默认的PBKDF2舍入计数大约是您希望的86倍。AES-128-CCM可能很好。
在以上三个选项中,SJCL哭泣的可能性最小。但是有更好的选择。
您无需在密码模式,哈希函数和其他不必要选项的菜单之间进行选择。您永远不会冒险搞砸参数并从协议中删除所有安全性。
相反,libsodium只是为您提供了针对最大安全性和简约API进行了调整的简单选项。
crypto_box()/ crypto_box_open()提供经过身份验证的公钥加密。
crypto_secretbox()/ crypto_secretbox_open()提供共享密钥验证的加密。
另外,libsodium具有数十种流行编程语言的绑定,因此libsodium很可能在尝试与另一个编程堆栈进行互操作时才可以工作。同样,libsodium往往非常快而不会牺牲安全性。
首先,您需要决定一件事:
如果选择了第一个选项,请获取CipherSweet.js。
该文档可在线获得。EncryptedField在大多数情况下就足够了,但是如果您要加密很多不同的字段,则EncryptedRow和EncryptedMultiRowsAPI可能会更容易。
有了CipherSweet,您甚至不需要知道安全地使用它的随机数/ IV。
此外,这可以处理int/ float加密,而不会通过密文大小泄漏有关内容的事实。
否则,您将需要sodium-plus,它是各种libsodium包装器的用户友好前端。使用Sodium-Plus,您可以编写易于审计和推理的高性能,异步,跨平台代码。
要安装sodium-plus,只需运行...
npm install sodium-plus
Run Code Online (Sandbox Code Playgroud)
当前没有用于浏览器支持的公共CDN。这将很快改变。但是,如果需要,可以sodium-plus.min.js从最新的Github版本中获取。
npm install sodium-plus
Run Code Online (Sandbox Code Playgroud)
钠加的文档可在Github上找到。
如果您需要分步教程,那么这篇dev.to文章将为您提供所需的内容。
在实施任何这些之前,请参阅Scott Arciszewski 的回答。
我希望你对我将要分享的内容非常小心,因为我几乎没有安全知识(我很可能滥用下面的 API),所以我非常欢迎更新这个答案在社区的帮助下。
正如@richardtallent 在他的回答中提到的,支持 Web Crypto API,因此本示例使用标准。在撰写本文时,全球浏览器支持 95.88%。
我将分享一个使用 Web Crypto API 的示例
在我们继续之前,请注意(引自 MDN):
此 API 提供了许多低级加密原语。这是很容易滥用它们,和陷阱参与可以非常微妙。
即使假设您正确使用了基本的加密功能,安全密钥管理和整体安全系统设计也很难做到正确,并且通常是专业安全专家的领域。
安全系统设计和实施中的错误会使系统的安全性完全失效。
如果您不确定自己知道自己在做什么,那么您可能不应该使用这个 API。
我非常尊重安全性,我什至在 MDN 中加粗了其他部分......你已经被警告
现在,到实际例子......
在这里找到: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.
Run Code Online (Sandbox Code Playgroud)
const encryptedUri = await crypto.subtle.encrypt({
name: 'RSA-OAEP'
}, key.publicKey, stringToArrayBuffer(stringToEncrypt))
console.log('The encrypted string is', encryptedUri);
Run Code Online (Sandbox Code Playgroud)
const msg = await crypto.subtle.decrypt({
name: 'RSA-OAEP',
}, key.privateKey, encryptedUri);
console.log(`Derypted Uri is ${arrayBufferToString(msg)}`)
Run Code Online (Sandbox Code Playgroud)
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;
}
Run Code Online (Sandbox Code Playgroud)
您可以在此处找到更多示例(我不是所有者):// https://github.com/diafygi/webcrypto-examples
您可以使用这些函数,第一个加密非常简单,因此您只需调用该函数并发送您想要加密的文本,然后从 encryptWithAES 函数获取结果并将其发送到解密函数,如下所示:
const CryptoJS = require("crypto-js");
//The Function Below To Encrypt Text
const encryptWithAES = (text) => {
const passphrase = "My Secret Passphrase";
return CryptoJS.AES.encrypt(text, passphrase).toString();
};
//The Function Below To Decrypt Text
const decryptWithAES = (ciphertext) => {
const passphrase = "My Secret Passphrase";
const bytes = CryptoJS.AES.decrypt(ciphertext, passphrase);
const originalText = bytes.toString(CryptoJS.enc.Utf8);
return originalText;
};
let encryptText = encryptWithAES("YAZAN");
//EncryptedText==> //U2FsdGVkX19GgWeS66m0xxRUVxfpI60uVkWRedyU15I=
let decryptText = decryptWithAES(encryptText);
//decryptText==> //YAZAN
Run Code Online (Sandbox Code Playgroud)
使用MDN Web Docs提供的加密 api :
https://developer.mozilla.org/en-US/docs/Web/API/Crypto
使用简单加密
使用加密()和解密()
要使用 SimpleCrypto,首先使用密钥(密码)创建一个 SimpleCrypto 实例。创建 SimpleCrypto 实例时必须定义密钥参数。
要加密和解密数据,只需使用实例中的 加密() 和解密() 函数即可。这将使用 AES-CBC 加密算法。
var _secretKey = "some-unique-key";
var simpleCrypto = new SimpleCrypto(_secretKey);
var plainText = "Hello World!";
var chiperText = simpleCrypto.encrypt(plainText);
console.log("Encryption process...");
console.log("Plain Text : " + plainText);
console.log("Cipher Text : " + cipherText);
var decipherText = simpleCrypto.decrypt(cipherText);
console.log("... and then decryption...");
console.log("Decipher Text : " + decipherText);
console.log("... done.");
Run Code Online (Sandbox Code Playgroud)