incapaz de datos decrypt en el Nodo que se cifra en Java usando AES-GCM-256

Danny Galiyara:

Estoy tratando de hacer una API Node.js en el que descifra la entrada que se ha creado mediante AES-GCM-256 algo, estoy usando el mismo algo en JAVA para cifrar el código, pero no soy capaz de descifrarlo usando nodo. js

He intentado muchos métodos, pero estoy atascado tal vez en la parte de etiquetas y estoy consiguiendo el error 'estado no compatible o no puede autenticar los datos'

Mi código Java:

import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
​
public class AES256GCMAlgo {
​
​
        static String plainText = "This is a plain text which need to be encrypted by Java AES 256 GCM Encryption Algorithm";
        public static final int AES_KEY_SIZE = 256;
        public static final int GCM_IV_LENGTH = 12;
        public static final int GCM_TAG_LENGTH = 16;
​
        public static void main(String[] args) throws Exception
        {
            KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
            keyGenerator.init(AES_KEY_SIZE);
​
            // Generate Key
            SecretKey key = keyGenerator.generateKey();
            byte[] IV = new byte[GCM_IV_LENGTH];
            SecureRandom random = new SecureRandom();
            random.nextBytes(IV);
​
            byte[] encoded = key.getEncoded();
            String output = Base64.getEncoder().withoutPadding().encodeToString(encoded);
            System.out.println("Keep it secret, keep it safe! " + output);
​
​
            String ivoutput = Base64.getEncoder().withoutPadding().encodeToString(IV);
            System.out.println("Keep ivoutput secret, keep it safe! " + ivoutput);
​
            System.out.println("Original Text : " + plainText);
​
            byte[] cipherText = encrypt(plainText.getBytes(), key, IV);
​
            byte[] tagVal = Arrays.copyOfRange(cipherText, cipherText.length - (128 / Byte.SIZE), cipherText.length);
​
            System.out.println("Encrypted Text : " + Base64.getEncoder().encodeToString(cipherText));
​
            System.out.println("Tag Text : " + Base64.getEncoder().encodeToString(tagVal));
​
​
            String input = output ;
            byte[] deencoded = Base64.getDecoder().decode(output);
            SecretKey aesKey = new SecretKeySpec(deencoded, "AES");
​
            String ivinput = ivoutput;
            byte[] ivdeencoded = Base64.getDecoder().decode(ivinput);
​
            String decryptedText = decrypt(cipherText, aesKey, ivdeencoded);
            System.out.println("DeCrypted Text : " + decryptedText);
        }
​
        public static byte[] encrypt(byte[] plaintext, SecretKey key, byte[] IV) throws Exception
        {
            // Get Cipher Instance
            Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
​
            // Create SecretKeySpec
            SecretKeySpec keySpec = new SecretKeySpec(key.getEncoded(), "AES");
​
            // Create GCMParameterSpec
            GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, IV);
​
            // Initialize Cipher for ENCRYPT_MODE
            cipher.init(Cipher.ENCRYPT_MODE, keySpec, gcmParameterSpec);
​
            // Perform Encryption
            byte[] cipherText = cipher.doFinal(plaintext);
​
​
​
            return cipherText;
        }
​
        public static String decrypt(byte[] cipherText, SecretKey key, byte[] IV) throws Exception
        {
            // Get Cipher Instance
            Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
​
            // Create SecretKeySpec
            SecretKeySpec keySpec = new SecretKeySpec(key.getEncoded(), "AES");
​
            // Create GCMParameterSpec
            GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, IV);
​
            // Initialize Cipher for DECRYPT_MODE
            cipher.init(Cipher.DECRYPT_MODE, keySpec, gcmParameterSpec);
​
            // Perform Decryption
            byte[] decryptedText = cipher.doFinal(cipherText);
​
            return new String(decryptedText);
        }
    }

Mi código de Node.js

const crypto = require('crypto');
// input created by running above program in java
const ed = 'OGtANbvTLY6Cme2VNAxsiIhBLLwl29oVX7zC5DGmmq4hU/VqNKaGQuSp1Q8liQ94cW/B96OJoJJ2r67jRlQFI4qHCTWFU2qQ8QaNj6WehdVLsf5mDK2aMYjc/vXd1ha/cElMBzFaIp9g==='
const key = 'HuzPEZgzqKOo8VwlnYhNUaPWTWSVDRQ2bMtY6aJAp8I'
const iv = 'kg5ILA0826hrew5w'
const tag = 'jc/vXd1ha/cElMBzFaIp9g==' // last 16 bytes extracted in java

function decrypt(encrypted, ik, iiv, it) {
  let bData = Buffer.from(encrypted, 'base64');
  // console.log(bData.length,bData.length - 64)
  let tag1 = Buffer.from(tag, 'base64');
  // let tag1 = bData.slice((bData.length - 16),bData.length) // also tried slicing last 16 bytes of buffer
  console.log('00000000',tag1.length)
  let iv1 = Buffer.from(iiv, 'base64');
  let key1 = new Buffer(ik, 'base64');
  console.log('aaaaaaaaa')
  let decipher = crypto.createDecipheriv('aes-256-gcm', key1, iv1)
  console.log('bbbbbbbbbbbbb')
  decipher.setAuthTag(tag1);
  console.log('ccccccc')
  let dec = decipher.update(encrypted, 'binary', 'utf8')
  dec += decipher.final('utf8');
  return dec;
}

console.log('devryptedddddd',decrypt(ed,key,iv,tag))

que debería obtener 'Se trata de un texto que deben ser cifrados por AES Java 256 GCM algoritmo de cifrado' en la consola de Node.js, pero estoy consiguiendo "estado no compatible o no puede autenticar los datos de error. ayuda amablemente.

dave_thompson_085:

El 'ed' que su uso no es la salida de ese código Java para ese texto plano, clave, y IV. El valor que se ve es en base 64

OGtANbvTLY6Cme2VNAxsiIhBLLwl29oVX7zC5DGmmq4hU/VqNKaGQuSp1Q8liQ94cW/B96OJoJJ2r67jRlQFI4qHCTWFU2qQ8QaNj6WehdVLsf5mDK2aMY3P713dYWv3BJTAcxWiKfY=

(los últimos 22 caracteres son diferentes). Sin embargo, ese valor no es el valor correcto a utilizar en nodejs; Cripto Java devuelve la etiqueta de GCM como la última N bytes del texto cifrado, y que lo copió correctamente desde allí a una variable independiente, pero no eliminarlo de texto cifrado. El texto cifrado correcta a utilizar en nodejs es en base 64:

OGtANbvTLY6Cme2VNAxsiIhBLLwl29oVX7zC5DGmmq4hU/VqNKaGQuSp1Q8liQ94cW/B96OJoJJ2r67jRlQFI4qHCTWFU2qQ8QaNj6WehdVLsf5mDK2aMQ==

(20 caracteres más cortos y de los 3 últimos caracteres diferente).

Por último, sus nodejs hace bData = Buffer.from(encrypted, 'base64')pero luego ignora bDatay hace decipher.update(encrypted, 'binary', 'utf8')- utilizando la cadena de base 64 como binario, lo que no lo es. Con esos dos cambios:

const crypto = require('crypto');

const ed = 'OGtANbvTLY6Cme2VNAxsiIhBLLwl29oVX7zC5DGmmq4hU/VqNKaGQuSp1Q8liQ94cW/B96OJoJJ2r67jRlQFI4qHCTWFU2qQ8QaNj6WehdVLsf5mDK2aMQ=='
const key = 'HuzPEZgzqKOo8VwlnYhNUaPWTWSVDRQ2bMtY6aJAp8I'
const iv = 'kg5ILA0826hrew5w'
const tag = 'jc/vXd1ha/cElMBzFaIp9g==' // last 16 bytes extracted in java

function decrypt(encrypted, ik, iiv, it) {
  let bData = Buffer.from(encrypted, 'base64');
  let tag1 = Buffer.from(tag, 'base64');
  let iv1 = Buffer.from(iiv, 'base64');
  let key1 = new Buffer(ik, 'base64');
  let decipher = crypto.createDecipheriv('aes-256-gcm', key1, iv1)
  decipher.setAuthTag(tag1);
  let dec = decipher.update(bData, 'utf8')
  dec += decipher.final('utf8');
  return dec;
}
console.log(decrypt(ed,key,iv,tag))

Me da la salida correcta, sino también una advertencia de que new Buffer()(utilizado para key1) está en desuso; Buffer.fromque utilizó para las otras variables ahora se prefiere.

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=332727&siteId=1
Recomendado
Clasificación