Шифрование / дешифрование AES в Node JS аналогично Java - PullRequest
2 голосов
/ 18 февраля 2020

Я пытаюсь повторить код Java для Шифрование и дешифрование AES в Node JS.

Java Код

    SecretKeySpec skeySpec;
    String key = "a4e1112f45e84f785358bb86ba750f48";

    public void encryptString(String key) throws Exception {
        try {
            skeySpec = new SecretKeySpec(key.getBytes(), "AES");
            cipher = Cipher.getInstance("AES");
            cipher.init(1, skeySpec);
            byte encstr[] = cipher.doFinal(message.getBytes());
            String encData = new String(encstr, "UTF-8");
            System.out.println(encData);
        } catch (NoSuchAlgorithmException nsae) {
            throw new Exception("Invalid Java Version");
        } catch (NoSuchPaddingException nse) {
            throw new Exception("Invalid Key");
        }
    }

Node JS

    var encryptKey = function (text) {
        var cipher = crypto.createCipher('aes256', 'a4e1112f45e84f785358bb86ba750f48');
        var crypted = cipher.update(text,'utf8', 'hex')
        crypted += cipher.final('hex');
        console.log(crypted);
        return crypted;
    }

Я не могу получить точный зашифрованный текст в Node JS, который я получаю в Java.

Ответы [ 2 ]

1 голос
/ 20 февраля 2020

Наконец, после просмотра Java Документы и Node JS Крипто-документы удалось получить результат. Мы должны использовать crypto.createCipheriv() вместо crypto.createCipher с iv. Здесь iv будет null.

Код:

    let crypto = require('crypto');

    var iv = new Buffer.from('');   //(null) iv 
    var algorithm = 'aes-256-ecb';
    var password = 'a4e1112f45e84f785358bb86ba750f48';      //key password for cryptography

    function encrypt(buffer){
        var cipher = crypto.createCipheriv(algorithm,new Buffer(password),iv)
        var crypted = Buffer.concat([cipher.update(buffer),cipher.final()]);
        return crypted;
    }

    console.log(encrypt(new Buffer('TextToEncrypt')).toString())
1 голос
/ 18 февраля 2020

Ваш код фактически использует разные параметры шифрования в 2 случаях. AES, являясь блочным шифром, принимает: простой текст для шифрования, вектор инициализации, также называемый IV (который используется вместе с открытым текстом), и ключ шифрования.

В Java, IV, по-видимому, генерируется автоматически в init () - из документации Java SE для Cipher.init:

Сгенерированные параметры можно получить с помощью getParameters или getIV. (если параметром является IV).

В Node.js, если используется устаревшая функция createCipher , IV генерируется автоматически на основе предоставленного ключа, вероятно, в иначе, чем в Java, поэтому вы получите другой зашифрованный текст. Тем не менее, вы должны использовать не устаревший вариант crypto.createCipheriv : https://nodejs.org/docs/latest-v12.x/api/crypto.html#crypto_crypto_createcipheriv_algorithm_key_iv_options

Чтобы точно воспроизвести зашифрованный текст, вы должны:

  • Используйте один и тот же алгоритм шифрования с обеих сторон - лучше указать это точно, например, aes-256-cb c, или аутентифицированную схему шифрования, такую ​​как aes-256-gcm , который сложнее в использовании, но обеспечивает аутентификацию сообщений.
  • Используйте один и тот же IV с обеих сторон, предоставив его в параметрах инициализации в Java и с помощью createCipheriv в узле; хотя будьте осторожны, вы всегда должны рандомизировать его в производстве! См. { ссылка }

В качестве заключительного замечания, при использовании блочного шифрования вы, как правило, будете генерировать безопасные случайные IV, что означает, что шифротексты всегда будут отличаться друг от друга даже за тот же открытый текст. Это хорошая вещь! Он защищает ваши данные от злоумышленника, который наблюдает зашифрованные данные и делает выводы на основе повторений сообщений.

...