我正在使用以下示例在Node.js中进行签名+验证:https://github.com/nodejs/node-v0.x-archive/issues/6904.验证在Node.js中成功,但在WebCrypto中失败.同样,使用WebCrypto签名的消息无法在Node.js中进行验证.
这是我用来验证使用WebCrypto从Node.js脚本生成的签名的代码 - https://jsfiddle.net/aj49e8sj/.在Chrome 54.0.2840.27和Firefox 48.0.2中进行了测试
// From https://github.com/nodejs/node-v0.x-archive/issues/6904
var keys = {
priv: '-----BEGIN EC PRIVATE KEY-----\n' +
'MHcCAQEEIF+jnWY1D5kbVYDNvxxo/Y+ku2uJPDwS0r/VuPZQrjjVoAoGCCqGSM49\n' +
'AwEHoUQDQgAEurOxfSxmqIRYzJVagdZfMMSjRNNhB8i3mXyIMq704m2m52FdfKZ2\n' +
'pQhByd5eyj3lgZ7m7jbchtdgyOF8Io/1ng==\n' +
'-----END EC PRIVATE KEY-----\n',
pub: '-----BEGIN PUBLIC KEY-----\n' +
'MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEurOxfSxmqIRYzJVagdZfMMSjRNNh\n' +
'B8i3mXyIMq704m2m52FdfKZ2pQhByd5eyj3lgZ7m7jbchtdgyOF8Io/1ng==\n' +
'-----END PUBLIC KEY-----\n'
};
var message = (new TextEncoder('UTF-8')).encode('hello');
// Algorithm used in Node.js script is ecdsa-with-SHA1, key generated with prime256v1
var algorithm = {
name: 'ECDSA',
namedCurve: 'P-256',
hash: {
name: 'SHA-1'
}
};
// Signature …Run Code Online (Sandbox Code Playgroud) 使用JavaScript和WebCrypto API(不使用任何外部库),使用从用户提交的密码派生的密钥对字符串进行加密的最佳方法是什么?
这是一些代码,其中键不是派生的,而是仅由generatekey()函数生成的。目标是加密字符串,然后解密它以验证我们是否返回了原始字符串:
var secretmessage = "";
var password = "";
var key_object = null;
var promise_key = null;
var encrypted_data = null;
var encrypt_promise = null;
var vector = window.crypto.getRandomValues(new Uint8Array(16));
var decrypt_promise = null;
var decrypted_data = null;
function encryptThenDecrypt() {
secretmessage = document.getElementById("secretmessageField").value; // some string to encrypt
promise_key = window.crypto.subtle.generateKey(
{
name: "AES-GCM",
length: 128
},
false,
["encrypt", "decrypt"]
);
promise_key.then(function(key) {
key_object = key;
encrypt_data();
});
promise_key.catch = function(e) {
alert("Error while generating …Run Code Online (Sandbox Code Playgroud) 该网络加密API支持的浏览器通过JavaScript本地cryptograhic功能,例如一个可靠的随机数生成器或用于加密或签名不同算法的可能性的使用。
该规范列出了算法概述作为实现者的起点,但添加了以下编辑说明:
注意:列出的所有算法都应被视为“有风险的功能”,除非实现者采用它们。它们包含在编辑器草案中反映了社区成员对它们包含的请求,并作为练习被包含在内,以确保本规范中定义的 API 的健壮性。
因此,算法列表和建议可能会在未来的修订中发生重大变化。
据我了解,规范背后的想法是为密码学提供一个接口,而不是写下特定的算法(这完全有道理!)。
如何确定客户端是否支持特定算法?隐藏实现细节是一种很好的做法,但是由于算法必须具有所谓的公认算法名称,我不明白为什么您不想公开已注册的算法。仍然没有指定接口,您注册算法的对象描述如下:
这个规范使用了一个内部对象,[[supportedAlgorithms]]。
此内部对象不向应用程序公开。
在当前状态发现可用算法的唯一可能性是捕获微妙接口的NotSupportedError。
从我的角度来看,发现是简单的程序流程,错误应该作为异常处理,而不是实现逻辑。
任何提示或建议?也欢迎链接到适当的 w3c-mailinglist 讨论。
我试图解密使用OpenSSL命令行界面创建的文件.此文件创建于:
openssl aes-256-cbc -a -in file.txt -out file_encrypted.txt
并可以解密:
openssl aes-256-cbc -d -a -in file_encrypted.txt
通过使用-p标志,我可以检索WebCrypto API所需的实际值salt和IV:
> openssl aes-256-cbc -d -a -p -in file_encrypted.txt
salt=F57F1CC0CD384326
key=0E971326890959386F1CFB91F185CFE109203DCEBC81DCAD4EE642F34C538E5B
iv=A884549B66400EB198879F8A09148D4E
secret text
Run Code Online (Sandbox Code Playgroud)
我目前的尝试看起来像这样:
function getKey (password) {
return crypto.subtle.digest({name: "SHA-256"}, convertStringToArrayBufferView(password)).then(function(result){
return crypto.subtle.importKey("raw", result, {name: "AES-CBC"}, false, ["encrypt", "decrypt"]);
});
}
function decrypt(key, data, iv) {
return crypto.subtle.decrypt({ name: "AES-CBC", iv: iv }, key, data).then(function(result){
var decrypted_data = new Uint8Array(result);
return convertArrayBufferViewtoString(decrypted_data);
}, fail);
}
var encrypted = Uint8Array.from('0E971326890959386F1CFB91F185CFE109203DCEBC81DCAD4EE642F34C538E5B'.match(/\w\w/g));
var …Run Code Online (Sandbox Code Playgroud) 我将 CryptoKey 导出为 PEM 样式,现在我想将其导入回来。我使用以下代码生成了密钥:
function generate() {
return window.crypto.subtle.generateKey(
{
name: "RSA-OAEP",
modulusLength: 2048,
publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
hash: {name: "SHA-256"},
},
true,
["encrypt", "decrypt"]
).then(function (key) {
return key;
})
.catch(function (err) {
console.error(err);
});
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试使用以下代码导入字符串(pem 样式)的私钥:
function importPrivateKey(pemKey) {
return crypto.subtle.importKey("pkcs8", convertPemToBinary(pemKey), {name:"RSA-OAEP", hash:{name:"SHA-256"}}, true, ["encrypt", "decrypt"]);}
Run Code Online (Sandbox Code Playgroud)
不幸的是,它返回这个错误:
SyntaxError: Cannot create a key using the specified key usages.
Run Code Online (Sandbox Code Playgroud)
更新
ConvertPemToBinary 函数
function convertPemToBinary(pem) {
var lines = pem.split('\n');
var encoded = '';
for (var i …Run Code Online (Sandbox Code Playgroud) 我正在尝试在 nodejs 中加密一段字符串,并且需要在前端 javascript 中对其进行解密。在 nodejs 中,我使用了加密库,而在前端使用了网络加密。在前端解密时遇到一些错误。
节点
const crypto = require('crypto');
const iv = crypto.randomBytes(12);
const algorithm = 'aes-256-gcm';
let password = 'passwordpasswordpasswordpassword';
let text = 'Hello World!';
let cipher = crypto.createCipheriv(algorithm, password, iv);
let encrypted = cipher.update(text, 'utf8', 'hex');
encrypted += cipher.final('hex');
var tag = cipher.getAuthTag();
let cipherObj = {
content: encrypted,
tag: tag,
iv: iv
}
Run Code Online (Sandbox Code Playgroud)
前端
let cipherObj; //GET FROM BE
let aesKey = await crypto.subtle.importKey(
"raw",
Buffer.from('passwordpasswordpasswordpassword'), //password
"AES-GCM",
true,
["decrypt"]
);
let decrypted = …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用crypto.subtle.encrypt来加密一些数据,但遇到了我一次可以加密的数据量的问题。使用 RSA-OAEP 的 2048 位密钥的最大块大小为 214 字节,如链接crypto.stackexchange.com和 stackoverflow.com 中使用关系所示maxChunkSizeInBytes = keySizeInBytes – 42。
使用crypto.subtle.encrypt2048 位密钥和 RSA-OAEP 算法,我只能加密 190 字节。低于 190 字节的任何数量都可以正常工作,高于 190 字节的任何数量都会导致错误。我不完全确定错误的类型(因为我无法捕捉到它),但我认为它是一个OperationError参考developer.mozilla.org。
在这里所示的例子打字稿有两个数据块d1和d2与尺寸分别190个字节和214个字节。数据块d1加密得很好,但是d2 没有。
const MSG_LEN_1 = 190;
const MSG_LEN_2 = 214;
const d1 = (window.crypto.getRandomValues(new Uint8Array(MSG_LEN_1))).buffer;
const d2 = (window.crypto.getRandomValues(new Uint8Array(MSG_LEN_2))).buffer;
let encData = async (data: ArrayBuffer) => {
const key = await crypto.subtle.generateKey(
{
name: "RSA-OAEP",
modulusLength: …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用WebCrypto API加密大文件(> 1GB)。
加密小文件效果很好,但是当我尝试加密大文件时,我的浏览器挂起,而且似乎加密从未完成。
我认为最好的选择是读取和加密文件的块,而不是在读取完成后将这些块合并在一起。
这里有人有加密和合并块的经验吗?如果是这样,如果有人可以向我展示示例或指出正确的更正,我将不胜感激。
提前致谢!
我想使用 HKDF 作为密钥导出函数来实现椭圆曲线 diffie hellman。我在前端使用 python 后端和(普通)javascript。我在后端使用python 加密库,在前端使用Web Crypto api作为加密库。我在双方创建了 ECDH 密钥对并交换了公共密钥。现在我尝试使用交换的公钥和私钥以及 HKDF 算法创建 AES 共享密钥。我可以在 python 后端执行此操作(我按照此示例获取 python 代码):
def encrypt(public_key, secret):
global loaded_public_key
loaded_public_key = public_key
shared_key = server_private_key.exchange(ec.ECDH(), public_key)
IV = bytes("ddfbccae-b4c4-11", encoding="utf-8")
derived_key = HKDF(
algorithm=hashes.SHA256(),
length=32,
salt=None,
info=None,
).derive(shared_key)
aes = Cipher(algorithms.AES(derived_key), modes.GCM(IV))
encryptor = aes.encryptor()
padder = padding.PKCS7(128).padder()
padded_data = padder.update(secret.encode()) + padder.finalize()
return encryptor.update(secret.encode()) + encryptor.finalize()
Run Code Online (Sandbox Code Playgroud)
但我不知道如何使用网络加密 API 来做到这一点。这是我的尝试:(但不起作用)
async function deriveSecretKey(privateKey, publicKey) {
let sharedKey = …Run Code Online (Sandbox Code Playgroud) 私钥是使用椭圆曲线生成的。Web Crypto API 的SubtleCrypto接口中的方法似乎都无法从私钥派生公钥,如果我错了,请纠正我。我必须使用第三方库吗?
webcrypto-api ×10
javascript ×8
cryptography ×5
encryption ×5
aes-gcm ×1
ecdsa ×1
node.js ×1
openssl ×1
passwords ×1
rsa ×1
string ×1