简体   繁体   English

AES 解密 NodeJs 中的文件

[英]AES Decrypt a file in NodeJs

I have a JAVA code that does the AES encryption of excel file on the Windows Operating System.我有一个 JAVA 代码,它在 Windows 操作系统上对 excel 文件进行 AES 加密。 I want to decrypt the same file on the MacOs Operating System using NodeJS.我想使用 NodeJS 在 MacOs 操作系统上解密同一个文件。 I've written a decrypt function in NodeJs which is giving me the following error我在 NodeJs 中编写了一个解密函数,它给了我以下错误

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

Here is the JAVA Code这是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();
   }
}

Here is the NodeJs code to decrypt这是解密的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);
});

} }

I've created some examples in both Java and Node.js that will encrypt and decrypt files.我在 Java 和 Node.js 中创建了一些用于加密和解密文件的示例。 The code will be compatible as long as the same key and IV values are used, that is to say the Node code will decrypt the output from the Java and vice-versa.只要使用相同的密钥和 IV 值,代码就会兼容,也就是说 Node 代码将解密 Java 的输出,反之亦然。

Now I'm using text files as input here, but you can use any file type as input.现在我在这里使用文本文件作为输入,但您可以使用任何文件类型作为输入。

I've updated to use 128-bit AES in ECB mode.我已更新为在 ECB 模式下使用 128 位 AES。

The Key cannot be "1234" since it must be 128-bits long, so I've used the key given below (16 bytes / 128 bits).密钥不能是“1234”,因为它必须是 128 位长,所以我使用了下面给出的密钥(16 字节/128 位)。

Java爪哇

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();
    }
}

Node.js节点.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");

I have solved this problem with the help of Terry Lennox .我在Terry Lennox的帮助下解决了这个问题。 A big thanks to him first.首先非常感谢他。

First Error:第一个错误:

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

This was a padding issue, By default, nodeJs uses PKCS padding so I had to set auto padding to false by using decipher.setAutoPadding(false);这是一个填充问题,默认情况下,nodeJs 使用 PKCS 填充,因此我必须使用decipher.setAutoPadding(false);将自动填充设置为 false decipher.setAutoPadding(false);

This solved the first error这解决了第一个错误

Secondly, I was using crypto.createDecipher(ALGORITHM, ENCRYPTION_KEY) which processes the key before using it.其次,我正在使用crypto.createDecipher(ALGORITHM, ENCRYPTION_KEY)在使用它之前处理密钥。 To solve this I changed the function to crypto.createDecipheriv(ALGORITHM, ENCRYPTION_KEY, null)为了解决这个问题,我将函数更改为crypto.createDecipheriv(ALGORITHM, ENCRYPTION_KEY, null)

This was giving me error as we cannot pass null in place of IV value.这给了我错误,因为我们不能通过null代替 IV 值。

Since ECB does not require any IV, and we cannot pass null in place of IV I had to set my IV value to this Buffer.alloc(0)由于 ECB 不需要任何 IV,而且我们不能通过 null 代替 IV 我不得不将我的 IV 值设置为此Buffer.alloc(0)

This is the code that worked for me这是对我有用的代码

function Decrypt_AES() {

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

    var IV = Buffer.alloc(0);
    var decipher = crypto.createDecipheriv(ALGORITHM, ENCRYPTION_KEY, IV);
    decipher.setAutoPadding(false);
    var input = fs.createReadStream('test.enc');
    var output = fs.createWriteStream('test_copy.xls');

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

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

} }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM