Зашифруйте строку в nodejs и расшифруйте в java - PullRequest
0 голосов
/ 05 июля 2018

Я шифрую текст в NODEJS и пытаюсь расшифровать в Java, но получаю ошибку. код моего nodejs:

var crypto = require('crypto')
  , key = 'mykey@91'
  , plaintext = 'SS18617710213463'
  , cipher = crypto.createCipher('aes-128-ecb', key)
  , decipher = crypto.createDecipher('aes-128-ecb', key);



var encryptedPassword = cipher.update(plaintext, 'utf8', 'base64');

encryptedPassword += cipher.final('base64')

var decryptedPassword = decipher.update(encryptedPassword, 'base64', 'utf8');
decryptedPassword += decipher.final('utf8');

console.log('original  :', plaintext); 
console.log('encrypted :', encryptedPassword);
console.log('decrypted :', decryptedPassword);

но когда я пытаюсь расшифровать его, он всегда выдает ошибку.

public static String decrypt(String encryptedText) {
    try {
         final String key = "mykey@91";
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(), "AES");
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        byte[] cipherText = Base64.getDecoder().decode(encryptedText.getBytes("UTF8"));
        String decryptedString = new String(cipher.doFinal(cipherText),"UTF8");
        return decryptedString;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

Ошибка, которую я получаю, как показано ниже:

java.security.InvalidKeyException: неверная длина ключа AES: 8 байт

1 Ответ

0 голосов
/ 06 июля 2018

Причина, по которой вы получаете Invalid AES key length: 8 bytes invalid AES, связана с длиной вашего ключа и текста. Вы должны убедиться, что его длина в битах является степенью двойки. Если вы хотите использовать String в качестве ключа шифрования, проверьте его длину в байтах и ​​умножьте на 8, чтобы найти длину в битах. Также для большинства реализаций String потребуется 2 байта на каждый символ (Java 64bit). Подробная информация здесь: Как решить InvalidKeyException

В этом случае упомянутая ошибка исчезнет только при использовании дополнительной клавиши или более длинной клавиши, например:

static String PLAIN_TEXT = "SS18617710213463"; 
static String ENCRYPTION_KEY = "mykey@91mykey@91";

Однако есть еще одна важная вещь для рассмотрения. Реализация Java должна соответствовать точным алгоритмам, предоставленным node.js. Это не так просто, как кажется (по крайней мере, исходя из моего опыта). В вашем случае я бы предложил вам использовать node-forge на стороне node.js, что проще для реализации Java:

var forge = require('node-forge');

var plaintext = 'SS18617710213463';  
var key = 'mykey@91mykey@91';
var iv = 'AODVNUASDNVVAOVF';

console.log('Plain Text: ' + plaintext); 

var cipher = forge.cipher.createCipher('AES-CBC', key);
cipher.start({iv: iv});
cipher.update(forge.util.createBuffer(plaintext));
cipher.finish();
var encrypted = cipher.output;

var encodedB64 = forge.util.encode64(encrypted.data);
console.log("Encoded: " + encodedB64);

var decodedB64 = forge.util.decode64(encodedB64);
encrypted.data = decodedB64;

var decipher = forge.cipher.createDecipher('AES-CBC', key);
decipher.start({iv: iv});
decipher.update(encrypted);
var result = decipher.finish(); 

console.log("Decoded: " + decipher.output.data);

Запустив приведенный выше код, выведите:

Plain Text: SS18617710213463
Encoded: HCzZD7uc13fqfM6odWcXf/mdR4aNJfkMDhEbnU+asjE=
Decoded: SS18617710213463

И совместимый код Java, который будет работать аналогичным образом, выглядит как приведенный ниже код:

import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class Main {

    static String PLAIN_TEXT = "SS18617710213463"; 
    static String ENCRYPTION_KEY = "mykey@91mykey@91";
    static String INITIALIZATIO_VECTOR = "AODVNUASDNVVAOVF";

    public static void main(String [] args) {
        try {

            System.out.println("Plain text: " + PLAIN_TEXT);

            byte[] encryptedMsg = encrypt(PLAIN_TEXT, ENCRYPTION_KEY);
            String base64Encrypted = Base64.getEncoder().encodeToString(encryptedMsg);
            System.out.println("Encrypted: "+  base64Encrypted);

            byte[] base64Decrypted = Base64.getDecoder().decode(base64Encrypted);
            String decryptedMsg = decrypt(base64Decrypted, ENCRYPTION_KEY);
            System.out.println("Decrypted: " + decryptedMsg);
        } catch (Exception e) { 
            e.printStackTrace();
        } 
    }

    public static byte[] encrypt(String plainText, String encryptionKey) throws Exception {
        Cipher cipher = Cipher.getInstance("AES/CBC/pkcs5padding", "SunJCE");
        SecretKeySpec key = new SecretKeySpec(encryptionKey.getBytes("UTF-8"), "AES");
        cipher.init(Cipher.ENCRYPT_MODE, key,new IvParameterSpec(INITIALIZATIO_VECTOR.getBytes("UTF-8")));
        return cipher.doFinal(plainText.getBytes("UTF-8"));
      }

      public static String decrypt(byte[] cipherText, String encryptionKey) throws Exception{
        Cipher cipher = Cipher.getInstance("AES/CBC/pkcs5padding", "SunJCE");
        SecretKeySpec key = new SecretKeySpec(encryptionKey.getBytes("UTF-8"), "AES");
        cipher.init(Cipher.DECRYPT_MODE, key,new IvParameterSpec(INITIALIZATIO_VECTOR.getBytes("UTF-8")));
        return new String(cipher.doFinal(cipherText),"UTF-8");
      }
}

Который производит:

Plain text: SS18617710213463
Encrypted: HCzZD7uc13fqfM6odWcXf/mdR4aNJfkMDhEbnU+asjE=
Decrypted: SS18617710213463
...