AES-GCM-256を使用してJavaで暗号化されているノードでデータを復号化することができません

ダニーGaliyara:

私は、コードを暗号化するためにJAVAで同じアルゴを使用していますが、私はノードを使用してそれを解読することはできませんよ、AES-GCM-256アルゴを使用して作成された入力を復号化しNode.jsの中にAPIを作成しようとしています。 JS

私持っているが、多くのアプローチを試みたが、私は、タグ部分に多分立ち往生しています&i「はサポートされていない状態やデータを認証することができない」のエラーを取得しています

私の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);
        }
    }

マイ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))

私はNode.jsののコンソールではなく、i「はサポートされていない状態やデータ認証できない」というエラーを取得しています「これは、Java AES 256 GCM暗号化アルゴリズムによって暗号化する必要がプレーンテキストである」取得する必要があります。親切に助け。

dave_thompson_085:

「ED」あなたの使用は、その平文、キー、およびIVのためにそのJavaコードの出力ではありません。私が取得値は、base64であります

OGtANbvTLY6Cme2VNAxsiIhBLLwl29oVX7zC5DGmmq4hU/VqNKaGQuSp1Q8liQ94cW/B96OJoJJ2r67jRlQFI4qHCTWFU2qQ8QaNj6WehdVLsf5mDK2aMY3P713dYWv3BJTAcxWiKfY=

(最後の22の文字は異なります)。しかし、その値はnodejsで使用する正しい値ではありません。Javaの暗号リターンは、最後のNとしてGCMタグは、暗号文のバイト、あなたは正しく、そこから別の変数にコピーされたが、あなたはしませんでした暗号文から削除します。nodejsで使用する正しい暗号文は、base64であります:

OGtANbvTLY6Cme2VNAxsiIhBLLwl29oVX7zC5DGmmq4hU/VqNKaGQuSp1Q8liQ94cW/B96OJoJJ2r67jRlQFI4qHCTWFU2qQ8QaNj6WehdVLsf5mDK2aMQ==

(20文字より短くし、最後の3つの文字は異なります)。

最後に、あなたのnodejsはありませんbData = Buffer.from(encrypted, 'base64')が、その後無視bDataしていdecipher.update(encrypted, 'binary', 'utf8')-それはないバイナリとしてbase64文字列を、使用して。これら二つの変更の場合:

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))

私は正しい出力するだけでなく、という警告を取得new Buffer()(のために使用key1は推奨されません)を、Buffer.fromあなたが他の変数のために使用されるようになりまし好ましいです。

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=332724&siteId=1