gpt4 book ai didi

javascript - 在 Javascript 中加密并在 Java 中解密 Zip 文件

转载 作者:行者123 更新时间:2023-11-30 14:00:21 33 4
gpt4 key购买 nike

我想用javascript加密本地zip文件,然后用java解密。

我使用了这个链接 https://www.devglan.com/corejava/aes-encryption-javascript-and-decryption-in-java 中的代码

在 javascript 中加密

var AesUtil = function (keySize, iterationCount) {
this.keySize = keySize / 32;
this.iterationCount = iterationCount;
};

AesUtil.prototype.generateKey = function (salt, passPhrase) {
var key = CryptoJS.PBKDF2(
passPhrase,
CryptoJS.enc.Hex.parse(salt),
{keySize: this.keySize, iterations: this.iterationCount});
return key;
};

AesUtil.prototype.encrypt = function (salt, iv, passPhrase, plainText) {
var key = this.generateKey(salt, passPhrase);
var encrypted = CryptoJS.AES.encrypt(
plainText,
key,
{iv: CryptoJS.enc.Hex.parse(iv)});
return encrypted.ciphertext.toString(CryptoJS.enc.Base64);
};

AesUtil.prototype.decrypt = function (salt, iv, passPhrase, cipherText) {
var key = this.generateKey(salt, passPhrase);
var cipherParams = CryptoJS.lib.CipherParams.create({
ciphertext: CryptoJS.enc.Base64.parse(cipherText)
});
var decrypted = CryptoJS.AES.decrypt(
cipherParams,
key,
{iv: CryptoJS.enc.Hex.parse(iv)});
return decrypted.toString(CryptoJS.enc.Utf8);


};

var CryptoJS = require('crypto-js'),
fs = require('fs');

var data = fs.readFileSync("C:\\<my_path>\\scripts.zip");

var passPhrase = "123456789123456789";
var iv = "a145525c53eafb0258999612b13d9d3e"; //CryptoJS.lib.WordArray.random(128 / 8).toString(CryptoJS.enc.Hex);
var salt = "ca70e17a698096cfb42047926713dd62";// CryptoJS.lib.WordArray.random(128 / 8).toString(CryptoJS.enc.Hex);

var aesUtil = new AesUtil(128, 1000);
var ciphertext = aesUtil.encrypt(salt, iv, passPhrase, data.toString());

fs.writeFileSync('C:/Output.encrypted', ciphertext);

在java中解密是这样的:AesUtil.java

import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;

import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;

public class AesUtil {
private final int keySize;
private final int iterationCount;
private final Cipher cipher;

public AesUtil(int keySize, int iterationCount) {
this.keySize = keySize;
this.iterationCount = iterationCount;
try {
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
}
catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
throw fail(e);
}
}

public String decrypt(String salt, String iv, String passphrase, String ciphertext) {
try {
SecretKey key = generateKey(salt, passphrase);
byte[] decrypted = doFinal(Cipher.DECRYPT_MODE, key, iv, base64(ciphertext));
return new String(decrypted, "UTF-8");
}
catch (UnsupportedEncodingException e) {
return null;
}catch (Exception e){
return null;
}
}

public byte[] doFinal(int encryptMode, SecretKey key, String iv, byte[] bytes) {
try {
cipher.init(encryptMode, key, new IvParameterSpec(hex(iv)));
return cipher.doFinal(bytes);
}
catch (InvalidKeyException
| InvalidAlgorithmParameterException
| IllegalBlockSizeException
| BadPaddingException e) {
return null;
}
}

public SecretKey generateKey(String salt, String passphrase) {
try {
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec(passphrase.toCharArray(), hex(salt), iterationCount, keySize);
SecretKey key = new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES");
return key;
}
catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
return null;
}
}

public static byte[] base64(String str) {
return Base64.decodeBase64(str);
}

public static byte[] hex(String str) {
try {
return Hex.decodeHex(str.toCharArray());
}
catch (DecoderException e) {
throw new IllegalStateException(e);
}
}

private IllegalStateException fail(Exception e) {
return null;
}

}

主要方法:

private static void mainScan(String[] args) {
try {
String keyString = "123456789123456789";


int keySize = 128;
int iterationCount = 1000;
String iv = "a145525c53eafb0258999612b13d9d3e";
String salt = "ca70e17a698096cfb42047926713dd62";
AesUtil aesUtil = new AesUtil(keySize, iterationCount);


String encryptedPath = "C:/Output.encrypted";
String decryptedPath = "C:/Output.zip";


String fileString = new String(Files.readAllBytes(Paths.get(encryptedPath)));
String decryptedText = aesUtil.decrypt(salt, iv, keyString, fileString);

FileUtils.writeStringToFile(new File(decryptedPath), decryptedText);
} catch (IOException e) {
e.printStackTrace();
}
}

但是,在解密之后,我得到了一个比原始 zip 更大的 zip 文件,并且不是有效的 zip 文件。

  • 注意:当文本只是字符串而不是从/到文件中获取字符串时,此代码有效

最佳答案

在大多数语言中,将 Zip 文件等二进制内容视为字符串通常是一个大错误。在 Javascript 方面,CryptoJS 期望将任意字节序列作为 CryptoJS.lib.WordArray 参数提供。

所以,而不是

var ciphertext = aesUtil.encrypt(salt, iv, passPhrase, data.toString());

你应该有

var ciphertext = aesUtil.encrypt(salt, iv, passPhrase, CryptoJS.lib.WordArray.create(data));

在 Java 端,更改函数 decrypt 以返回 byte[]

public byte[] decrypt(String salt, String iv, String passphrase, String ciphertext) {
SecretKey key = generateKey(salt, passphrase);
byte[] decrypted = doFinal(Cipher.DECRYPT_MODE, key, iv, base64(ciphertext));
return decrypted;
}

main 中,将代码更改为如下所示

String fileString = new String(Files.readAllBytes(Paths.get(encryptedPath)));
byte [] decryptedText = aesUtil.decrypt(salt, iv, keyString, fileString);
Files.write(Paths.get(decryptedPath), decryptedText);

关于javascript - 在 Javascript 中加密并在 Java 中解密 Zip 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56415724/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com