есть ли дротический эквивалент следующей функции шифрования Aes в Java - PullRequest
4 голосов
/ 26 апреля 2019

Я настроил сервер, который прослушивает зашифрованный байтовый массив с помощью функции Java, упомянутой ниже. Ранее я использовал java (android) для создания своего приложения, поэтому было легко использовать ту же функцию java, но я не могу понять, что такое дротический эквивалент (трепетание) этой функции, которая принимает строку в качестве входного и возвращает зашифрованный AES байтовый массив в качестве вывода, который я могу записать в сокет TCP.

Также я был бы очень признателен, если бы знал, как записать сгенерированный байтовый массив на сервер, а затем прочитать аналогичный ответ и расшифровать его с помощью dart (трепетание)

Я успешно писал простые строки и получал простые строки в качестве ввода и вывода на tcp-сервер через dart, но не могу сделать то же самое для зашифрованных байтовых массивов. В Java я использовал DataOutputStream для отправки ответа на сервер, как это

DataOutputStream dOut = newDataOutputStream(socket.getOutputStream());

           byte[] s2 = Encrypt3.encrypt2(myString);

           dOut.writeInt(s2.length); // write length of the message
            dOut.write(s2);

Вот java-функция, которую я использовал для шифрования aes

import java.security.Key;

import javax.crypto.Cipher;

import javax.crypto.spec.SecretKeySpec;


public class Encrypt3 {
public static String key = "mykey";

public static byte[] encrypt2(String text ){
    String encrypt ="";

    try{
        // Create key and cipher
        Key aesKey = new SecretKeySpec(key.getBytes(), "AES");
        Cipher cipher = Cipher.getInstance("AES");
        // encrypt the text
        cipher.init(Cipher.ENCRYPT_MODE, aesKey);
        byte[] encrypted = cipher.doFinal(text.getBytes());
        return encrypted ;
    }catch(Exception e){
        System.out.println(e);
    }
    return null ;
}


public static String decrypt2(byte[] encrypted2){
    String decrypt ="";
    try{
        Key aesKey = new SecretKeySpec(key.getBytes(), "AES");
        Cipher cipher = Cipher.getInstance("AES");
        // decrypt the text
        cipher.init(Cipher.DECRYPT_MODE, aesKey);
        decrypt = new String(cipher.doFinal(encrypted2));
    }catch(Exception e){
        System.out.println(e);
    }

    return decrypt ;
}


}

Я ожидаю, что эквивалентный байтовый массив будет создан в dart, если ему будет предоставлена ​​строка в качестве входных данных, а затем записать байтовый массив на tcp-сервер.

Заранее спасибо

1 Ответ

1 голос
/ 26 апреля 2019

При настройке шифра Java по умолчанию используется режим электронной кодовой книги (ECB), который не должен использоваться в реальной системе шифрования.Вы также полагаетесь на заполнение по умолчанию - PKCS5.

Используйте пакет pointcastle со следующим импортом:

import 'package:pointycastle/api.dart';
import 'package:pointycastle/block/aes_fast.dart';
import 'package:pointycastle/paddings/pkcs7.dart';
import 'package:pointycastle/padded_block_cipher/padded_block_cipher_impl.dart';
import 'package:pointycastle/block/modes/ecb.dart';

Примерный эквивалент в Dart:

List<int> encrypt2(String text) {
  // key must be 16 or 32 bytes - not sure how "mykey" could work
  // key should really be binary, not a String! Better to use a KDF.
  Uint8List key = Uint8List.fromList(
    utf8.encode('0123456789abcdef'),
  );

  PaddedBlockCipher cipher = PaddedBlockCipherImpl(
    PKCS7Padding(), // Java defaults to PKCS5 which is equivalent
    ECBBlockCipher(AESFastEngine()), // Very weak mode - don't use this in the real world
  );

  cipher.init(
    true,
    PaddedBlockCipherParameters<CipherParameters, CipherParameters>(
      KeyParameter(key),
      null,
    ),
  );

  return cipher.process(utf8.encode(text)); // this isn't the same as .toBytes, except for ASCII
}
...