首页 > 解决方案 > AES 解密 NodeJs 中的文件

问题描述

我有一个 JAVA 代码,可以在 Windows 操作系统上对 excel 文件进行 AES 加密。我想使用 NodeJS 在 MacOs 操作系统上解密相同的文件。我在 NodeJs 中编写了一个解密函数,它给了我以下错误

error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt

这是JAVA代码

import java.security.Key;
import java.io.OutputStream;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

public class fileEncrypter {
   try {
     final SecretKeySpec key = new SecretKeySpec("1234".getBytes(), "AES");
     final Cipher instance = Cipher.getInstance("AES/ECB/PKCS5Padding");
     final BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(name));
     final BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(name2));
     instance.init(1, key);
     final byte[] b = new byte[4096];
     for (int i = bufferedInputStream.read(b); i > -1; i = bufferedInputStream.read(b)) {
        final byte[] update = instance.update(b, 0, I);
        bufferedOutputStream.write(update, 0, update.length);
     }
     bufferedInputStream.close();
     final byte[] doFinal = instance.doFinal();
     bufferedOutputStream.write(doFinal, 0, doFinal.length);
     bufferedOutputStream.flush();
     bufferedOutputStream.close();
     return "success";
   } catch(Exception obj) {
     System.err.println("Exception occured while encryption:" + obj);
     obj.printStackTrace();
     return obj.toString();
   }
}

这是解密的NodeJs代码

function Decrypt_AES() {

const ALGORITHM = 'aes-128-ecb';
const ENCRYPTION_KEY = "1234";

var decipher = crypto.createDecipher(ALGORITHM, ENCRYPTION_KEY);
decipher.setAutoPadding(true);
var input = fs.createReadStream('test.enc');
var output = fs.createWriteStream('test_copy.xls');

input.pipe(decipher).pipe(output);

output.on('finish', function () {
    console.log('Encrypted file written to disk!');
});
output.on('error', function (e) {
    console.log(e);
});

}

标签: javanode.jsencryption

解决方案


我在 Java 和 Node.js 中创建了一些用于加密和解密文件的示例。只要使用相同的密钥和 IV 值,代码就会兼容,也就是说,Node 代码将解密 Java 的输出,反之亦然。

现在我在这里使用文本文件作为输入,但您可以使用任何文件类型作为输入。

我已更新为在 ECB 模式下使用 128 位 AES。

密钥不能是“1234”,因为它必须是 128 位长,所以我使用了下面给出的密钥(16 字节/128 位)。

爪哇

import java.io.*;
import javax.crypto.*;
import java.security.*;
import javax.crypto.spec.*;

public class fileEncrypter {

  private static final String key = "0123456789ABDCEF";

  public static void main(String[] args)
  {
      encryptFile(key, "java-input.txt", "java-output.txt");
      decryptFile(key, "java-output.txt", "java-decrypted.txt");
  }

  public static void encryptFile(String secret, String inputFile, String outputFile) 
  {
      try 
      {
          Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
          cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(secret.getBytes(), "AES"));

          byte[] inputData = readFile(inputFile);
          byte[] outputData = cipher.doFinal(inputData);
          writeToFile(outputFile, outputData);  
      } 
      catch (Exception e) 
      {
          System.out.println("Error while encrypting: " + e.toString());
      }
  }

  public static void decryptFile(String secret, String inputFile, String outputFile) 
    {
        try 
        {
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
            cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(secret.getBytes(), "AES"));

            byte[] inputData = readFile(inputFile);
            byte[] outputData = cipher.doFinal(inputData);
            writeToFile(outputFile, outputData);  
        } 
        catch (Exception e) 
        {
            System.out.println("Error while decrypting: " + e.toString());
        }
    }

    private static byte[] readFile(String fileName) throws IOException {
        byte[] data = new byte[(int) new File(fileName).length()];
        DataInputStream dis = new DataInputStream(new FileInputStream(fileName));
        dis.readFully(data);
        dis.close();
        return data;
    }

    private static void writeToFile(String fileName, byte[] data) throws IOException {
        final BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(fileName));
        bufferedOutputStream.write(data, 0, data.length);
        bufferedOutputStream.close();
    }
}

节点.js

const crypto = require("crypto");
const Algorithm = "aes-128-ecb";
const fs = require("fs");

function encryptFile(key, inputFile, outputFile) {
    const inputData = fs.readFileSync(inputFile);
    const cipher = crypto.createCipheriv(Algorithm, key, Buffer.alloc(0));
    const output = Buffer.concat([cipher.update(inputData) , cipher.final()]);
    fs.writeFileSync(outputFile, output);
}

function decryptFile(key, inputFile, outputFile) {
    const inputData = fs.readFileSync(inputFile);
    const cipher = crypto.createDecipheriv(Algorithm, key, Buffer.alloc(0));
    const output = Buffer.concat([cipher.update(inputData) , cipher.final()]);
    fs.writeFileSync(outputFile, output);
}

const KEY = Buffer.from("0123456789ABDCEF", "utf8");

encryptFile(KEY, "node-input.txt", "node-output.txt");
decryptFile(KEY, "node-output.txt", "node-decrypted.txt");

推荐阅读