Jas*_*son 16 javascript java encryption cryptography aes
编辑1
在decryptFile方法中,解密部分不会输出任何内容.
let decrypted = CryptoJS.AES.decrypt(e.target.result, CryptoJS.enc.Utf8.parse(key), {
iv: CryptoJS.enc.Utf8.parse(iv),
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
Run Code Online (Sandbox Code Playgroud)
编辑2评论部分中给出 的链接部分解决了问题.它确实对跨平台进行加密和解密,但由于PBKDF2具有SHA256散列,它相当慢.我找不到只使用AES部分而不是PKBDF2部分的方法.
原文
我对Java和Javascript版本使用相同的密钥和IV.我无法解密用Java加密的Javascript中的文件,也无法解密用Javascript加密的Java文件.我需要这两个兼容彼此,但我无法弄清楚我是如何尝试解密以前用Java加密的Javascript中的文件.我已经成功地在两者之间实现了解密和加密文本,但是当我想要解密一个用Java加密的文件时,它就无法工作了.
用Java加密/解密文件:
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class Test {
private SecretKey secretKey;
private IvParameterSpec ivParameterSpec;
private String key = "ThisIsMyGreatKey";
private byte[] ivKey = "ABCDEFGHabcdefgh".getBytes();
public static void main(String[] args) {
try {
new Test().run();
} catch (Exception e) {
e.printStackTrace();
}
}
private void run() {
ivParameterSpec = new IvParameterSpec(ivKey);
secretKey = new SecretKeySpec(key.getBytes(), "AES");
encryptOrDecryptFile(Cipher.ENCRYPT_MODE,
new File("src/cactus.jpg"), new File("src/cactus-encrypted.jpg"));
}
private void encryptOrDecryptFile(int mode, File inputFile, File outputFile) {
try {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(mode, secretKey, ivParameterSpec);
// Read input
byte[] input = new byte[(int) inputFile.length()];
FileInputStream inputStream = new FileInputStream(inputFile);
inputStream.read(input);
// Encrypt and write to output
byte[] output = cipher.doFinal(input);
FileOutputStream outputStream = new FileOutputStream(outputFile);
outputStream.write(output);
inputStream.close();
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Run Code Online (Sandbox Code Playgroud)
在Javascript中加密/解密
<input type="file" id="file-input" onchange="handleFile(this)">
<button onclick="useEncryptionForFile()" id="encrypt-file">Encrypt File</button>
<button onclick="useDecryptionForFile()" id="decrypt-file">Decrypt File</button>
<textarea id="output"></textarea>
<img id="example">
<script>
let key = "ThisIsMyGreatKey";
let iv = "ABCDEFGHabcdefgh";
let useEncryption, useDecryption;
let input = document.getElementById("file-input");
let output = document.getElementById("output");
let example = document.getElementById("example");
function handleFile(element) {
if (element.files && element.files[0]) {
let file = element.files[0];
if (useDecryption) {
decryptFile(file);
} else {
encryptFile(file);
}
}
}
function encryptFile(file) {
let reader = new FileReader();
reader.onload = function (e) {
let encrypted = CryptoJS.AES.encrypt(e.target.result, CryptoJS.enc.Utf8.parse(key), {
iv: CryptoJS.enc.Utf8.parse(iv),
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
output.textContent = encrypted;
let a = document.createElement("a");
a.setAttribute('href', 'data:application/octet-stream,' + encrypted);
a.setAttribute('download', file.name + '.encrypted');
a.click();
};
reader.readAsDataURL(file);
}
function decryptFile(file) {
let reader = new FileReader();
reader.onload = function (e) {
let decrypted = CryptoJS.AES.decrypt(e.target.result, CryptoJS.enc.Utf8.parse(key), {
iv: CryptoJS.enc.Utf8.parse(iv),
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
// Decrypted is emtpy
output.textContent = decrypted;
// Desperate try to get something working
example.src = "data:image/png;base64," + btoa(decrypted);
let a = document.createElement("a");
a.setAttribute('href', decrypted);
a.setAttribute('download', file.name.replace('encrypted', 'decrypted'));
a.click();
};
reader.readAsText(file);
}
function useEncryptionForFile() {
document.getElementById("encrypt-file").style.backgroundColor = "#757575";
document.getElementById("decrypt-file").style.backgroundColor = "#FFFFFF";
useEncryption = true;
useDecryption = false;
}
function useDecryptionForFile() {
document.getElementById("encrypt-file").style.backgroundColor = "#FFFFFF";
document.getElementById("decrypt-file").style.backgroundColor = "#757575";
useDecryption = true;
useEncryption = false;
}
</script>
Run Code Online (Sandbox Code Playgroud)
如果你想要更多:) 我也做了一个小提琴,并且可以在这里下载 Java源代码.
在Java源代码中,我使用cactus.jpg作为文件,但是可以使用任何文件:).仙人掌可以在这里找到.
如何解密用Java加密的文件?我已经尝试将blob内容转换为String,将数据检索为ArrayBuffer并将其转换为String,将其作为文本接收并将其传递给解密方法,但似乎没有任何效果.
我在Javascript中使用的库是CryptoJS,在Java中是标准的Crypto库.
我发现其他类似的(1,2)的问题.但是,我认为它们差别太大,因为这些问题的答案并不涉及这个问题,而是一个小错误.
如果我忘记了任何数据,请告诉我.
首先,尝试从 java 向 javascript 发送简单的加密文本,反之亦然,并测试代码是否正常工作。
如果代码适用于简单文本,即您能够从 Java 发送加密字符串并在 JavaScript 中成功解密,反之亦然,那么您可以做的是 Base64 编码加密字节/文件,然后传输文本并然后在另一端对其进行解码和解密。
如果代码不适用于简单文本,那么您可以尝试分别用 javascript 和 java 加密简单文本,并检查结果是否相同。如果不是,则说明 java 和 javascript 之间的加密/解密逻辑不匹配。
编辑:
正如您提到的代码适用于 String,我在下面展示了一个使用 java 中的 apache 通用编解码器库将文件转换为 Base64 String 的示例。
private static String encodeFileToBase64Binary(String fileName) throws IOException {
File file = new File(fileName);
byte[] encoded = Base64.encodeBase64(FileUtils.readFileToByteArray(file));
return new String(encoded, StandardCharsets.US_ASCII);
}
Run Code Online (Sandbox Code Playgroud)
现在您加密该字符串并将其发送到 javascript。在javascript中,首先解密字符串,然后将其转换为文件对象。
例如。
function base64toFile(encodedstring,filename,mimeType){
return new File([encodedstring.arrayBuffer()],filename, {type:mimeType});
}
//Usage example:
base64toFile('aGVsbG8gd29ybGQ=', 'hello.txt', 'text/plain');
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1472 次 |
| 最近记录: |