【问题标题】:Encryption in Flutter and Decryption in java (AES-256)Flutter 中的加密和 java 中的解密 (AES-256)
【发布时间】:2022-08-08 19:56:45
【问题描述】:

我正在尝试在 Flutter 中实现加密,我使用 java 作为后端和移动应用程序的 dart。我从这个Encryption in Java and Decryption in Flutter (AES-256) 中获取了代码 但它只在 Flutter 中提供解密,我想在 Flutter 中实现加密,以便 Java 代码可以解密它。

你能帮我提供 Flutter 中的加密代码吗?

这是用于加密和解密的java代码。

public class EncryptionService {
    public String encrypt(String item) throws Exception {
        byte[] ivBytes;
        String password = \"Hello\";
        /* you can give whatever you want for password. This is for testing purpose */
        SecureRandom random = new SecureRandom();
        byte bytes[] = new byte[20];
        random.nextBytes(bytes);
        byte[] saltBytes = bytes;
        // Derive the key
        SecretKeyFactory factory = SecretKeyFactory.getInstance(\"PBKDF2WithHmacSHA1\");

        PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), saltBytes, 65556, 256);

        SecretKey secretKey = factory.generateSecret(spec);
        SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), \"AES\");

        System.out.println(\"saltBytes : \" + saltBytes);

        // encrypting the word
        Cipher cipher = Cipher.getInstance(\"AES/CBC/PKCS5Padding\");
        cipher.init(Cipher.ENCRYPT_MODE, secret);
        AlgorithmParameters params = cipher.getParameters();
        ivBytes = params.getParameterSpec(IvParameterSpec.class).getIV();
        System.out.println(\"ivBytes : \" + ivBytes);

        byte[] encryptedTextBytes = cipher.doFinal(item.getBytes(\"UTF-8\"));
        // prepend salt and vi
        byte[] buffer = new byte[saltBytes.length + ivBytes.length + encryptedTextBytes.length];
        System.arraycopy(saltBytes, 0, buffer, 0, saltBytes.length);
        System.arraycopy(ivBytes, 0, buffer, saltBytes.length, ivBytes.length);
        System.arraycopy(encryptedTextBytes, 0, buffer, saltBytes.length + ivBytes.length, encryptedTextBytes.length);
        return new Base64().encodeToString(buffer);
    }

    public String decrypt(String encryptedText) throws Exception {
        String password = \"Hello\";
        Cipher cipher = Cipher.getInstance(\"AES/CBC/PKCS5Padding\");
        // strip off the salt and iv
        ByteBuffer buffer = ByteBuffer.wrap(new Base64().decode(encryptedText));
        byte[] saltBytes = new byte[20];
        buffer.get(saltBytes, 0, saltBytes.length);
        byte[] ivBytes1 = new byte[cipher.getBlockSize()];
        buffer.get(ivBytes1, 0, ivBytes1.length);
        byte[] encryptedTextBytes = new byte[buffer.capacity() - saltBytes.length - ivBytes1.length];

        buffer.get(encryptedTextBytes);
        // Deriving the key
        SecretKeyFactory factory = SecretKeyFactory.getInstance(\"PBKDF2WithHmacSHA1\");
        PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), saltBytes, 65556, 256);
        SecretKey secretKey = factory.generateSecret(spec);
        SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), \"AES\");
        cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(ivBytes1));
        byte[] decryptedTextBytes = null;
        try {
            decryptedTextBytes = cipher.doFinal(encryptedTextBytes);
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        }

        return new String(decryptedTextBytes);
    }
}

用于解密的 Dart 实现是这样的

class EncryptionHelper {
  static String decrypt(
    String ciphertext,
  ) {
    Uint8List ciphertextlist = base64.decode(ciphertext);
    var salt = ciphertextlist.sublist(0, 20);
    var iv = ciphertextlist.sublist(20, 20 + 16);
    var encrypted = ciphertextlist.sublist(20 + 16);

    Uint8List key = generateKey(\"Hello\", salt);
    CBCBlockCipher cipher = new CBCBlockCipher(new AESFastEngine());

    ParametersWithIV<KeyParameter> params =
        new ParametersWithIV<KeyParameter>(new KeyParameter(key), iv);

    PaddedBlockCipherParameters<ParametersWithIV<KeyParameter>, Null>
        paddingParams =
        new PaddedBlockCipherParameters<ParametersWithIV<KeyParameter>, Null>(
            params, null);
    PaddedBlockCipherImpl paddingCipher =
        new PaddedBlockCipherImpl(new PKCS7Padding(), cipher);
    paddingCipher.init(false, paddingParams);
    var val = paddingCipher.process(encrypted);

    return new String.fromCharCodes(val);
  }

  static Uint8List generateKey(String passphrase, Uint8List salt) {
    Uint8List passphraseInt8List = Uint8List.fromList(passphrase.codeUnits);

    KeyDerivator derivator =
        PBKDF2KeyDerivator(HMac(SHA1Digest(), 64)); // 64 byte block size
    Pbkdf2Parameters params =
        Pbkdf2Parameters(salt, 65556, 32); // 32 byte key size
    derivator.init(params);
    return derivator.process(passphraseInt8List);
  }
}
  • 由于这是关于使用 Flutter 进行加密的,因此您应该发布最新的 Flutter 代码加密.目前您只发布了解密代码。
  • @Topaco 我不知道如何编写加密代码。我只是在网上复制了代码。
  • 你不会\'reverse\'解密吗?以同样的方式导出密钥,在paddingCipher.init() 中将 false 翻转为 true,然后按顺序组装 salt、iv 和 ct(考虑使用 BytesBuilder),最后对结果进行 base64 编码。复制 Java 代码对您有帮助,因为您可以在执行这些步骤时检查中间结果。 (当然你需要坚持使用固定盐。)
  • 作为故障排除的起点,请使用发布的解密代码和/或 PointyCastle 示例发布加密代码的初始版本。

标签: java flutter dart encryption pointycastle


【解决方案1】:

你为什么不使用 pointcastle ? 它是 Bouncy castle 的一个 dart 移植,正如我在他们的页面中所读到的,还有用于解密/加密的 AES 算法的实现。

此外使用:

https://pub.dev/packages/encrypt

这是 pointcastle 顶部的一个方便的包装器。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-10-16
    • 1970-01-01
    • 1970-01-01
    • 2015-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-13
    相关资源
    最近更新 更多