- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有使用 RC4 算法加密文件的代码。强烈建议我使用更可靠的算法:AES。从 CryptoJS 文档中,我了解到它的工作方式与 RC4 相同。即第一个参数为要加密的字符串,第二个参数为密码字符串。
但是简单地用 AES 替换 RC4 方法没有帮助,我不知道去哪里寻找必要的信息。
谢谢!
这是我的工作(用于 RC4)代码:
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js" integrity="sha512-E8QSvWZ0eCLGk4km3hxSsNmGWbLtSCSUcewDQPQWZF6pEU8GlT8a5fF32wOl1i8ftdMhssTrF/OhyGWwonTcXA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<div>
<h1>encrypt/decrypt file</h1>
<ol>
<li>Set password</li>
<li>Pick a file</li>
<li>Download decrypted/encrypted file</li>
</ol>
<div>
<input type="text" id="pass" placeholder="pass">
<button id="encrypt">encrypt file</button>
<button id="decrypt">decrypt file</button>
<button id="test">test</button>
</div>
</div>
<script>
// support
const download = (data, filename, type) => {
const file = new Blob([data], {
type: type
});
const a = document.createElement('a');
const url = URL.createObjectURL(file);
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
setTimeout(function() {
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
}, 0);
};
const pickAFile = (getText = true) => {
return new Promise((resolve, reject) => {
const input = document.createElement('input');
input.type = 'file';
input.onchange = (e) => {
const file = e.target.files[0];
const reader = new FileReader();
if (!getText) {
resolve(file);
} else {
reader.onload = (e) => resolve(e.target.result);
reader.onerror = (e) => reject(e);
reader.readAsText(file);
}
};
input.click();
});
};
const convertWordArrayToUint8Array = (wordArray) => {
const arrayOfWords = wordArray.hasOwnProperty('words') ? wordArray.words : [];
const length = wordArray.hasOwnProperty('sigBytes') ?
wordArray.sigBytes :
arrayOfWords.length * 4;
const uInt8Array = new Uint8Array(length);
let index = 0;
let word;
let i;
for (i = 0; i < length; i++) {
word = arrayOfWords[i];
uInt8Array[index++] = word >> 24;
uInt8Array[index++] = (word >> 16) & 0xff;
uInt8Array[index++] = (word >> 8) & 0xff;
uInt8Array[index++] = word & 0xff;
}
return uInt8Array;
};
// /support
function app() {
const passNode = document.querySelector('input#pass');
const encryptNode = document.querySelector('#encrypt');
const decryptNode = document.querySelector('#decrypt');
encryptNode.addEventListener('click', () => {
if (!passNode.value) return alert('Password input is empty! Aborting.');
const pass = CryptoJS.SHA3(passNode.value);
pickAFile(false).then((file) => {
const reader = new FileReader();
reader.onload = (e) => {
const wordArray = CryptoJS.lib.WordArray.create(e.target.result);
const encrypted = CryptoJS.RC4.encrypt(wordArray, pass).toString();
download(encrypted, `encrypted-${file.name}`, file.type);
};
reader.readAsArrayBuffer(file);
});
});
decryptNode.addEventListener('click', () => {
if (!passNode.value) return alert('Password input is empty! Aborting.');
const pass = CryptoJS.SHA3(passNode.value);
pickAFile(false).then((file) => {
const reader = new FileReader();
reader.onload = (e) => {
try {
const decrypted = CryptoJS.RC4.decrypt(e.target.result, pass);
const typedArray = convertWordArrayToUint8Array(decrypted);
download(typedArray, `decrypted-${file.name}`, file.type);
} catch (error) {
console.log('wrong password!');
}
};
reader.readAsText(file);
});
});
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', app);
} else {
app();
}
</script>
最佳答案
从 RC4 转换为 AES 时,请考虑以下事项:
AES 定义的 key 大小为 16 (AES-128)、24 (AES-192) 和 32 字节 (AES-256)。 key 越大,越安全(尽管如今所有变体都被认为是安全的)。下面使用 32 字节的 key 。
您应用的 SHA3 CryptoJS 实现(实际上是 Keccak,请参阅 Hashing/SHA-3)默认输出大小为 64 字节,因此不能直接用作 AES key 。因此,为简单起见,我应用输出大小为 32 字节的 SHA-256。您也可以使用 SHA-3 并且只取例如前 32 个字节。
但是,通过摘要推导 key 是一个漏洞。更安全的是使用像 Argon2 或 PBKDF2 这样的 key 派生。后者受 CryptoJS 支持,因此我建议切换到 PBKDF2。因为我在这里专注于将 RC4 转换为 AES,所以我会把更改留给你。
AES 在 CBC 模式(CryptoJS 默认使用;默认填充是 PKCS#7 btw)中需要一个随机 IV(其长度等于 block 大小,因此 AES 为 16 个字节)。出于安全原因,这不能是静态的,但必须为每次加密随机生成(使用 CSPRNG )。
IV 不是 secret 的,需要解密。因此通常与密文拼接:IV|ciphertext。
解密前根据已知的IV长度将IV和密文分开。
考虑到上述几点,从 RC4 到 AES 的可能转换是(另请参阅代码中的注释以了解更改的解释):
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js" integrity="sha512-E8QSvWZ0eCLGk4km3hxSsNmGWbLtSCSUcewDQPQWZF6pEU8GlT8a5fF32wOl1i8ftdMhssTrF/OhyGWwonTcXA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<div>
<h1>encrypt/decrypt file</h1>
<ol>
<li>Set password</li>
<li>Pick a file</li>
<li>Download decrypted/encrypted file</li>
</ol>
<div>
<input type="text" id="pass" placeholder="pass">
<button id="encrypt">encrypt file</button>
<button id="decrypt">decrypt file</button>
<button id="test">test</button>
</div>
</div>
<script>
// support
const download = (data, filename, type) => {
const file = new Blob([data], {
type: type
});
const a = document.createElement('a');
const url = URL.createObjectURL(file);
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
setTimeout(function() {
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
}, 0);
};
const pickAFile = (getText = true) => {
return new Promise((resolve, reject) => {
const input = document.createElement('input');
input.type = 'file';
input.onchange = (e) => {
const file = e.target.files[0];
const reader = new FileReader();
if (!getText) {
resolve(file);
} else {
reader.onload = (e) => resolve(e.target.result);
reader.onerror = (e) => reject(e);
reader.readAsText(file);
}
};
input.click();
});
};
const convertWordArrayToUint8Array = (wordArray) => {
const arrayOfWords = wordArray.hasOwnProperty('words') ? wordArray.words : [];
const length = wordArray.hasOwnProperty('sigBytes') ?
wordArray.sigBytes :
arrayOfWords.length * 4;
const uInt8Array = new Uint8Array(length);
let index = 0;
let word;
let i;
for (i = 0; i < length; i++) {
word = arrayOfWords[i];
uInt8Array[index++] = word >> 24;
uInt8Array[index++] = (word >> 16) & 0xff;
uInt8Array[index++] = (word >> 8) & 0xff;
uInt8Array[index++] = word & 0xff;
}
return uInt8Array;
};
// /support
function app() {
const passNode = document.querySelector('input#pass');
const encryptNode = document.querySelector('#encrypt');
const decryptNode = document.querySelector('#decrypt');
encryptNode.addEventListener('click', () => {
if (!passNode.value) return alert('Password input is empty! Aborting.');
const key = CryptoJS.SHA256(passNode.value); // Fix 1: Derive 32 bytes key
pickAFile(false).then((file) => {
const reader = new FileReader();
reader.onload = (e) => {
const iv = CryptoJS.lib.WordArray.random(16); // Fix 2: Create random 16 bytes IV
const wordArray = CryptoJS.lib.WordArray.create(e.target.result);
const encrypted = CryptoJS.AES.encrypt(wordArray, key, {iv: iv}); // Fix 3: Encrypt with AES using the above key and IV
const ivCiphertext = iv.clone().concat(encrypted.ciphertext).toString(CryptoJS.enc.Base64); // Fix 4: Concatenate IV and ciphertext
download(ivCiphertext, `encrypted-${file.name}`, file.type);
};
reader.readAsArrayBuffer(file);
});
});
decryptNode.addEventListener('click', () => {
if (!passNode.value) return alert('Password input is empty! Aborting.');
const key = CryptoJS.SHA256(passNode.value); // Fix 5: Derive 32 bytes key
pickAFile(false).then((file) => {
const reader = new FileReader();
reader.onload = (e) => {
try {
const ivCiphertext = CryptoJS.enc.Base64.parse(e.target.result); // Fix 6: Separate IV and ciphertext
const iv = CryptoJS.lib.WordArray.create(ivCiphertext.words.slice(0, 4));
const ciphertext = CryptoJS.lib.WordArray.create(ivCiphertext.words.slice(4));
const decrypted = CryptoJS.AES.decrypt({ciphertext: ciphertext}, key, {iv: iv}); // Fix 7: Decrypt
const typedArray = convertWordArrayToUint8Array(decrypted);
download(typedArray, `decrypted-${file.name}`, file.type);
} catch (error) {
console.log('wrong password!');
}
};
reader.readAsText(file);
});
});
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', app);
} else {
app();
}
</script>
请注意,代码仍然可以优化(这也适用于 RC4 变体):在加密期间,数据(即连接的 IV 和密文)是 Base64编码。 Base64 是一种二进制到文本的编码,可将数据大小增加约 33%。当要将任意二进制数据表示为文本时使用它。
但是,由于这里的数据是以文件的形式存储的,所以这样的转换并不是真正必要的(当然,也有可能是帖子中看不出来的原因)。相反,可以存储原始数据(即非 Base64 编码数据),这将相应地减小文件大小。
关于javascript - 如何使用 CryptoJS 使用 AES 算法加密文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73551878/
我正在使用框架的对象编写一个用于加密/解密的简单库。方法如下: public static byte[] Encrypt(byte[] key, byte[] vector, byte[] input
据我所知,RIM Crypto API 似乎只提供用于对称加密 (3Des) 的 PKCS5 填充模式。我正在使用 JDE 4.6.0。 我正在尝试为黑莓应用程序提供密码学,该应用程序需要与已经使用标
我已经获得了用于加密的 Java 实现,但遗憾的是我们是一家 .net 商店,我无法将 Java 整合到我们的解决方案中。可悲的是,我也不是 Java 专家,所以我已经为此苦苦挣扎了几天,我想我终于可
我正在尝试使用 KMS 和 AWS 加密 SDK 加密数据。查看 AWS documentation 中提供的示例,似乎没有地方可以明确设置数据 key 。 我找到了 EncryptionMateri
我目前有一个用于为我的网站制作哈希的代码,该代码使用 SALT 进行哈希处理,因此密码是不可逆的...... 目前它是 100% 为我的网站工作,它是使用 ASP.NET(C#) 编码的 这是我的代码
我想要做的是在 javascript 中生成一个 key 对,并在 PHP 中使用这些加密,然后用 JS 解密。 我在附加的代码中有两个问题 它不会从装甲文本块重新加载私钥 并且它不会解密 PHP 加
在进行密码哈希时,我有以下 node.js 代码。 body.password = covid@19 salt = "hello@world" body.passwordhex = crypto.cr
我想知道的是在配置文件中加密连接字符串的明确方法。以下是我的问题: 使用机器级加密,访问我的服务器的任何人都不能编写一个小的 .Net 程序来读取连接字符串的内容吗? 如果我将我的应用程序部署到企业环
我知道 rsync 可以在文件传输期间启用/禁用 ssh 加密协议(protocol)。那么,如果 ssh 加密协议(protocol)被禁用了,是不是意味着 rsync 根本不做任何加密呢? 另外,
脚本必须搜索网页内的字符串。但该脚本不应显示它正在搜索的字符串。我的意思是搜索字符串应该采用加密格式或任何其他格式。但如果没有该搜索字符串,则不应显示网页或应在页面上显示错误。 我要开发一个插件。如果
我正在尝试加密 MySQL 上的某些字段。我正在使用 TPC-DS 的 v2.8 版本,并尝试在客户地址表的某些列上使用 AES。知道如何加密字段的所有行吗?我尝试使用 UPDATE customer
我需要一个简单的 javascript 函数,它允许我使用 key 加密 textarea 数据( key 是存储为散列 session 变量的用户密码,由 PHP 打印到字段中) 我基本上希望在用户
如何在 JavaScript 中散列/加密字符串值?我需要一种机制来隐藏 localStorage/cookie 中的一些数据吗? 这与安全问题有关,但我想为我的数据提供一些保护。 最佳答案 有很多
我有一个程序,其中数据库的密码由远程用户设置。该程序将用户名和密码保存到 xml 文件中的加密字符串中,否则应该是人类可读的。现在,这工作正常,我使用带有 key 的 C# DES 加密,它被加密和解
Kotlin 中是否有任何关于椭圆曲线加密的信息? 用于生成 key 对和加密、解密消息。 关于这个主题的信息很少甚至没有。 例如,我想实现 ECC P-521 椭圆曲线。 是否可以在 Kotlin
所以我知道 MD5 在技术上是新应用程序的禁忌,但我随机想到了这个: 自 md5($password); 不安全,不会 md5(md5($password)) 是更好的选择?我使用它的次数越多,它会变
我一直在努力使用 crypto_secretbox_easy() 在 libsodium 中加密/解密一些数据| .我似乎找不到关于使用的任何好的文档。 我想从用户那里获取密码,用它来以某种方式制作
我正在做一个加密项目 视频,我对这个程序有几个问题。 我用命令转码mp4至HLS与 ts段持续时间约为 10 秒。 首先,我需要使用数据库中的 key 加密这些视频。然而, 我不知道是否使用 ffmp
我有一个加密/复制保护问题。 我正在为使用加密狗的公司编写应用程序。请不要告诉我软件保护是没有用的,或者我应该让它自由地飞向空中,或者我花任何时间这样做都是浪费;这不是关于软件保护有效性的哲学问题,更
我对 有一个疑问VIM 加密 key . 我有一个文本文件,我使用加密该文件 :X 现在,加密 key 的存储位置(路径)。 无论是存储在单独的文件中还是存储在文本文件本身中。 如果我打开文件,它会询
我是一名优秀的程序员,十分优秀!