(Java to Javascript) эквивалентный код javax.crypto.Cipher в Nodejs Crypto Javascript

Я пытаюсь преобразовать код Java ниже в nodejs.


    private static String TRANS_MODE = "Blowfish";

    private static String BLOWFISH_KEY = "BLOWFISH_KEY";

    public static String encrypt(String password) throws Exception {

    SecretKeySpec keySpec = new SecretKeySpec(BLOWFISH_KEY.getBytes("Windows-31J"),TRANS_MODE);
    Cipher cipher;
    cipher = Cipher.getInstance(TRANS_MODE);

    cipher.init(Cipher.ENCRYPT_MODE, keySpec);
    byte[] passByte;
    passByte = cipher.doFinal(password.getBytes("Windows-31J"));


    return new String(Hex.encodeHex(passByte));

    }

Вот что я смог выяснить-



const crypto = require('crypto');

function encrypt(password)  
  var fcKey = "BLOWFISH_KEY";
  var cipher = crypto.createCipher('BF-CBC', fcKey, "");
  var encrypted = cipher.update(password,'ascii','hex');
  encrypted += cipher.final('hex');
return encrypted;

Я не могу получить такой же результат. Например, если

пароль = "пароль01"

Вывод кода Java — fe0facbf8d458adaa47c5fe430cbc0ad

Вывод кода Nodejs — ae5e8238c929b5716566e97fa35efb9b

Может кто поможет разобраться с проблемой??


person Dong Jin LEE    schedule 31.10.2019    source источник
comment
Dupe stackoverflow.com/questions/57447707/   -  person dave_thompson_085    schedule 31.10.2019


Ответы (1)


Обратите внимание, что crypto.createCipher(algorithm, password[, options]) устарел и не должен использоваться.

Где SecretKeySpec(..) в java принимает двоичный ключ в качестве входных данных, createCipher(..) в js принимает в качестве входных данных «пароль», а за сценой пытается получить двоичный ключ, используя MD5. Таким образом, ваш фактический ключ, используемый в двух программах, оказывается другим. Метод js также пытается получить IV из пароля, что является плохой практикой и отличается от вашего кода Java.

В js вам нужно использовать вместо этого crypto.createCipheriv(). И когда вы это сделаете, вам также нужно подумать, нужен ли iv - как в Java, так и в js.

person Ebbe M. Pedersen    schedule 31.10.2019
comment
Шифрование Java, когда вы указываете только такой алгоритм, как «BLOWFISH» (вместо «преобразования» = алгоритм/режим/заполнение), фактически использует заполнение в стиле ECB и PKCS5, тогда как шифрование nodejs использует OpenSSL, который по умолчанию используется, если необходимо для CBC (и PKCS5). У ECB нет IV, а также он небезопасен практически для всех целей (см. многочисленные вопросы по этому поводу в security.SX и crypto.SX); CBC действительно требует уникального и непредсказуемого IV. - person dave_thompson_085; 31.10.2019