简体   繁体   English

AES/CBC/PKCS5PADDING IV - NodeJs 中的解密(Java 加密)

[英]AES/CBC/PKCS5PADDING IV - Decryption in NodeJs (Encrypted in Java)

I am trying to decrypt in NodeJs.我正在尝试在 NodeJs 中解密。 It is working in Java.它在 Java 中工作。 But I am not able to achieve same in Node.但是我无法在 Node.js 中实现相同的目标。

node-version: 8.4节点版本:8.4

Please find my NodeJs code:请找到我的 NodeJs 代码:

var crypto = require('crypto');
function decryption (message, key) {
var messageArray = Buffer.from(message, 'base64');
  // var kekbuf =  Buffer(key, 'utf8');

  var ivBuffer = new Buffer([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]);
  var iv = ivBuffer.slice(0, 16);

  var decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
  decipher.setAutoPadding(false);
  var dec = decipher.update(messageArray, 'base64');

  dec += decipher.final();
  return dec.toString();
}

Please find working Java decryption code请找到有效的Java解密代码

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;

class Test1 {
  public String decrypt(String message, String key) throws Exception {
    DatatypeConverter dtc = null;
    byte[] messagArray = dtc.parseBase64Binary(message);
    byte[] keyArray = dtc.parseBase64Binary(key);

    byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
    IvParameterSpec ivspec = new IvParameterSpec(iv);

    SecretKey secretKey = new SecretKeySpec(keyArray, "AES");
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");

    cipher.init(Cipher.DECRYPT_MODE, secretKey, ivspec);
    return new String(cipher.doFinal(messagArray));
  }
}

I am getting a different decrypted text.我得到一个不同的解密文本。 I am not able to achieve the same result in NodeJs as I had in Java.我无法在 NodeJs 中获得与在 Java 中相同的结果。 Also, I could not modify my java encryption code.另外,我无法修改我的 java 加密代码。 So I have to figure out decryption in Node.所以我必须弄清楚 Node.js 中的解密。

Could you please help me with this.你能帮我解决这个问题吗?

Here are complete examples in Java and also Node.js, they use the same keys/iv/plaintext and will produce identical results.以下是 Java 和 Node.js 中的完整示例,它们使用相同的键/iv/plaintext 并将产生相同的结果。

Java爪哇

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.nio.charset.StandardCharsets;

class AES
{
    public AES()
    {
    }

    public String encrypt(String plainText, String keyBase64, String ivBase64) throws Exception
    {
        byte[] plainTextArray = plainText.getBytes(StandardCharsets.UTF_8);
        byte[] keyArray = DatatypeConverter.parseBase64Binary(keyBase64);
        byte[] iv = DatatypeConverter.parseBase64Binary(ivBase64);
        
        SecretKeySpec secretKey = new SecretKeySpec(keyArray, "AES");
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");   
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(iv));
        return new String(DatatypeConverter.printBase64Binary(cipher.doFinal(plainTextArray)));
    }
    
    public String decrypt(String messageBase64, String keyBase64, String ivBase64) throws Exception {

        byte[] messageArray = DatatypeConverter.parseBase64Binary(messageBase64);
        byte[] keyArray = DatatypeConverter.parseBase64Binary(keyBase64);
        byte[] iv = DatatypeConverter.parseBase64Binary(ivBase64);

        SecretKey secretKey = new SecretKeySpec(keyArray, "AES");
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
        cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(iv));
        return new String(cipher.doFinal(messageArray));
    }
  
    public static void main(String[] args) {
    
        try
        {   
            String plainText = "Hello world!";
            String encryptionKeyBase64 = "DWIzFkO22qfVMgx2fIsxOXnwz10pRuZfFJBvf4RS3eY=";
            String ivBase64 = "AcynMwikMkW4c7+mHtwtfw==";
            
            AES AES = new AES();
            
            String cipherText = AES.encrypt(plainText, encryptionKeyBase64, ivBase64);
            String decryptedCipherText = AES.decrypt(cipherText, encryptionKeyBase64, ivBase64);
            
            System.out.println("Plaintext: " + plainText);
            System.out.println("Ciphertext: " + cipherText);
            System.out.println("Decrypted text: " + decryptedCipherText);
        }
        catch (Exception e)
        {
            System.out.println(e.toString());
        }
    }
}

Node.js节点.js

var crypto = require('crypto');

function getAlgorithm(keyBase64) {
    
    var key = Buffer.from(keyBase64, 'base64');
    switch (key.length) {
        case 16:
            return 'aes-128-cbc';
        case 32:
            return 'aes-256-cbc';
            
    }
    
    throw new Error('Invalid key length: ' + key.length);
}


function encrypt(plainText, keyBase64, ivBase64) {

    const key = Buffer.from(keyBase64, 'base64');
    const iv = Buffer.from(ivBase64, 'base64');

    const cipher = crypto.createCipheriv(getAlgorithm(keyBase64), key, iv);
    let encrypted = cipher.update(plainText, 'utf8', 'base64')
    encrypted += cipher.final('base64');
    return encrypted;
};

function decrypt (messagebase64, keyBase64, ivBase64) {

    const key = Buffer.from(keyBase64, 'base64');
    const iv = Buffer.from(ivBase64, 'base64');

    const decipher = crypto.createDecipheriv(getAlgorithm(keyBase64), key, iv);
    let decrypted = decipher.update(messagebase64, 'base64');
    decrypted += decipher.final();
    return decrypted;
}


var keyBase64 = "DWIzFkO22qfVMgx2fIsxOXnwz10pRuZfFJBvf4RS3eY=";
var ivBase64 = 'AcynMwikMkW4c7+mHtwtfw==';
var plainText = 'Why, then, ’tis none to you, for there is nothing either good or bad, but thinking makes it so';

var cipherText = encrypt(plainText, keyBase64, ivBase64);
var decryptedCipherText = decrypt(cipherText, keyBase64, ivBase64);

console.log('Algorithm: ' + getAlgorithm(keyBase64));
console.log('Plaintext: ' + plainText);
console.log('Ciphertext: ' + cipherText);
console.log('Decoded Ciphertext: ' + decryptedCipherText);

Since I can't comment.因为我不能评论。 Above Node.js code fails to encrypt/decrypt for anything more than 15 characters/bytes.以上 Node.js 代码无法加密/解密超过 15 个字符/字节的任何内容。 Simple fix is as follows:简单的修复如下:

Change return to concatenate return of cipher.final and decipher.final将返回值cipher.finaldecipher.final连接返回值

 function encrypt(plainText, keyBase64, ivBase64) {

    var key = Buffer.from(keyBase64, 'base64');
    var iv = Buffer.from(ivBase64, 'base64');

    var cipher = crypto.createCipheriv(getAlgorithm(keyBase64), key, iv);
    let cip = cipher.update(plainText, 'utf8', 'base64')
    cip += cipher.final('base64');
    return cip;
};


function decrypt (messagebase64, keyBase64, ivBase64) {

    var key = Buffer.from(keyBase64, 'base64');
    var iv = Buffer.from(ivBase64, 'base64');

    var decipher = crypto.createDecipheriv(getAlgorithm(keyBase64), key, iv);
    let dec = decipher.update(messagebase64, 'base64');
    dec += decipher.final();
    return dec;
}

Check java conde conversion to Nodejs:检查 java conde 到 Nodejs 的转换:

Java:爪哇:

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
import java.util.Base64;

public class Main {

  private static final String ALGORITHM = "AES/CBC/PKCS5Padding";
  public static String encrypt(String message, String key) throws GeneralSecurityException, UnsupportedEncodingException {
    Cipher cipher = Cipher.getInstance(ALGORITHM);
    byte[] messageArr = message.getBytes();
    byte[] decodedBytes =   Base64.getDecoder().decode(key);
    SecretKeySpec keySpec = new
SecretKeySpec(Base64.getDecoder().decode(key), "AES");
    byte[] ivParams = new byte[16];

    byte[] encoded = new byte[messageArr.length + 16];
    System.arraycopy(ivParams,0,encoded,0,16);
    System.arraycopy(messageArr, 0, encoded, 16, messageArr.length);
    cipher.init(Cipher.ENCRYPT_MODE, keySpec, new IvParameterSpec(ivParams));
   
    byte[] encryptedBytes = cipher.doFinal(encoded);
    encryptedBytes = Base64.getEncoder().encode(encryptedBytes);
    return new String(encryptedBytes);
  }
  public static String decrypt(String encryptedStr, String key) throws GeneralSecurityException, UnsupportedEncodingException {
    Cipher cipher = Cipher.getInstance(ALGORITHM);
    SecretKeySpec keySpec = new
SecretKeySpec(Base64.getDecoder().decode(key), "AES");
    byte[] encoded = encryptedStr.getBytes();
    encoded = Base64.getDecoder().decode(encoded);
    
    byte[] decodedEncrypted = new byte[encoded.length-16];
    System.arraycopy(encoded, 16, decodedEncrypted, 0,encoded.length-16);
    byte[] ivParams = new byte[16];
    System.arraycopy(encoded,0, ivParams,0, ivParams.length);
    String ivString = new String(ivParams);
    
    cipher.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(ivParams));
    byte[] decryptedBytes = cipher.doFinal(decodedEncrypted);
    return new String(decryptedBytes);
  }

NodeJS:节点:

var crypto = require('crypto'); var crypto = require('crypto'); const encrypt = (plainText, keyBase64) =>{ const 加密 =(纯文本,keyBase64)=>{

    const textBuffer = Buffer.from(plainText);
    const key = Buffer.from(keyBase64, 'base64');
    var iv = Buffer.from([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]);
    var encoded = Buffer.concat([iv,textBuffer]);
    const cipher = crypto.createCipheriv('aes-192-cbc', key, iv);
    let encrypted = cipher.update(encoded, 'binary', 'base64')
    encrypted += cipher.final('base64');
    return encrypted;
};

const decrypt =  (messagebase64, keyBase64) =>{

    const key = Buffer.from(keyBase64, 'base64');
    const encoded = Buffer.from(messagebase64, 'base64');
    var iv = encoded.slice(0, 16);
    var decoded = encoded.slice(16,encoded.length);
    const decipher = crypto.createDecipheriv('aes-192-cbc', key, iv);
    let decrypted = decipher.update(decoded, 'binary','utf-8');
    decrypted += decipher.final();
    return decrypted;
}

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

相关问题 AES / CBC / PKCS5PADDING IV-从Java解密到NodeJs - AES/CBC/PKCS5PADDING IV - Decryption from Java to NodeJs 在使用带有“AES/CBC/PKCS5Padding”的 Java 密码进行解密时,是否必须指定 IV? 并且只能使用 SecretKeyFactory 吗? - In decryption using Java Cipher with “AES/CBC/PKCS5Padding”, must IV be specified? and only SecretKeyFactory can be used? Android / Java AES 256 CBC与PHP中的PKCS5Padding解密 - Android/Java AES 256 CBC with PKCS5Padding decryption in PHP NodeJs 中的 AES/CBC/PKCS5Padding - AES/CBC/PKCS5Padding in NodeJs PHP AES-256-CBC 加密数据不同于 JAVA AES/CBC/PKCS5PADDING - PHP AES-256-CBC encrypted data is different from JAVA AES/CBC/PKCS5PADDING AES CBC PKCS5将Java填充为Ruby - AES CBC PKCS5Padding Java to Ruby AES/CBC/PKCS5Padding 加密与固定 IV(或没有) - AES/CBC/PKCS5Padding encryption with fixed IV (or without one) 如何在angularJs中生成AES / CBC / PKCS5Padding加密密码 - How to generate AES/CBC/PKCS5Padding encrypted cipher in angularJs 客户端Java加密和服务器解密,使用PBKDF2WithHmacSHA1和AES / CBC / PKCS5Padding - Java encryption by client and decryption by server, using PBKDF2WithHmacSHA1 and AES/CBC/PKCS5Padding Java编程语言中AES/CBC/PKCS5Padding解密问题 - Question about AES / CBC / PKCS5Padding Decryption in the Java Programming Language
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM