NodeJs шифрование с использованием pbkdf2Syn c и расшифровка в java - PullRequest
1 голос
/ 20 марта 2020

Я шифрую некоторые данные в NodeJs, используя метод ниже. Он отлично работает на Nodejs сервер для шифрования и дешифрования.

Вход для шифрования = "SIYdcYSyiWY5XUqYMrfv31sPF8DSojs1ikghMs4R"

1004 * Зашифрованные выход в NodeJS = «IRhqmwhlFUxS1Zg + Qyr2ykSkAA1cQ5gVts7RIZoULCbYMS / DVsdfTyanGAAu4HkuAZv4ynk + VBPZ6vaTH5xTONfuVRlUavF9X // 12v5et5em1ItPYdlOWkYo5IkodpAQvm5Yrm4F5xaRxRU3 + TAZzOQm / 3YQIlz74X + 3V3 / aV / K4qFebSLUMZJM9glPWo4O + ISDf76ztiN2ynLyvsivSU / qUuQEtPVEK "
encryptAES = ((text) => {
    // random initialization vector
    const iv = crypto.randomBytes(16);

    const salt = crypto.randomBytes(64);

    var masterKey = crypto.randomBytes(32);

    const key = crypto.pbkdf2Sync(masterKey, salt, 2145, 32, 'sha512');

    // AES 256 GCM Mode
    const cipher = crypto.createCipheriv('aes-256-gcm', key, iv);

    const encrypted = Buffer.concat([cipher.update(text, 'utf8'), cipher.final()]);

    // extract the auth tag
    const tag = cipher.getAuthTag();

    // generate output
    return Buffer.concat([salt, iv, tag, masterKey, encrypted]).toString('base64');
});

Я пытаюсь расшифровать его по какой-то причине, но по какой-то причине * 1016 терпит неудачу. Я уверен, что я не использую правильный способ расшифровки. Ниже показано, как далеко я попал


    public String decrypt(String base64EncryptedData) throws Exception {

        byte[] decryptedData = Base64.getDecoder().decode(base64EncryptedData);

        byte[] salt =  Arrays.copyOfRange(decryptedData, 0, 64); 
        byte[] iv = Arrays.copyOfRange(decryptedData, 64, 80); 
        byte[] tag = Arrays.copyOfRange(decryptedData, 80, 96); 
        String masterKey = new String(Arrays.copyOfRange(decryptedData, 96, 128), "UTF-8"); 
        byte[] text = Arrays.copyOfRange(decryptedData, 128, decryptedData.length); ;
        GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(tag.length * 8, iv);

        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA512");
        KeySpec spec = new PBEKeySpec(masterKey.toCharArray(), salt, 2145, 32*8);
        SecretKey tmp = factory.generateSecret(spec);
        key = new SecretKeySpec(tmp.getEncoded(), "AES");
        dcipher = Cipher.getInstance("AES/GCM/NoPadding");
        dcipher.init(Cipher.DECRYPT_MODE, key, gcmParameterSpec);

        byte[] utf8 = dcipher.doFinal(text);
        return new String(utf8, "UTF8");
    }


В Java я получаю исключение

javax.crypto.AEADBadTagException: Tag mismatch!

1 Ответ

2 голосов
/ 21 марта 2020

В коде есть несколько проблем:

  • Самое серьезное, что пароль отправляется вместе с сообщением. Это позволяет любому расшифровать зашифрованный текст. Пароль должен быть секретным, его нельзя отправлять вместе с сообщением, его могут знать только отправитель и получатель.
  • Ключ tmp, полученный в коде Java с PBKDF2WithHmacSHA512, является экземпляром PBKDF2KeyImpl, который хранит пароль в char[], символы которого будут кодироваться в UTF8 (см. документацию класса PBKDF2KeyImpl). Однако в коде NodeJS пароль генерируется путем заполнения буфера псевдослучайно с использованием crypto.randomBytes. Случайные двоичные данные обычно не могут быть преобразованы в строку с использованием кодировки UTF8 без повреждения данных, здесь . Чтобы избежать этой проблемы, должны использоваться либо кодируемые данные UTF8, либо PKCS5S2ParametersGenerator BouncyCastle, который предполагает byte[]PBEParametersGenerator#init), в зависимости также от контекста, в котором применяется KDF ( например, получение ключа из пароля или из мастер-ключа, здесь ).
  • В Java зашифрованный текст и тег аутентификации обрабатываются не отдельно, а как один byte[], с тегом, добавленным в конец зашифрованного текста. В текущем коде Java тег аутентификации отделен, но нигде не используется (кроме как для ссылки на его длину в конструкторе GCMparameterSpec).
  • Также обратите внимание на рекомендации относительно параметров PBKDF2, особенно относительно количество итераций, RFC8018 , разделы 4.1 и 4.2 и здесь .
...