Shu*_*ham 3 encryption cryptography aes dart flutter
我正在解密 dart 中用 java 加密的文本。这是用于加密的java代码。
\npackage aes;\n\nimport java.security.InvalidKeyException;\nimport java.security.MessageDigest;\nimport java.util.Arrays;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport javax.crypto.Cipher;\nimport javax.crypto.spec.SecretKeySpec;\n\npublic class Aes {\n\n public static void main(String[] args) {\n try {\n\n String keyString = "1234567890123456";//length of key is 16\n Cipher desCipher = Cipher.getInstance("AES");\n byte[] key = keyString.getBytes("UTF-8");\n MessageDigest sha = MessageDigest.getInstance("SHA-1");\n key = sha.digest(key);\n key = Arrays.copyOf(key, 16); // use only first 128 bit\n\n SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");\n desCipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);\n\n String plainText = "abcd";\n\n byte[] text = plainText.getBytes("UTF-8");\n byte[] textencrypted = desCipher.doFinal(text);\n System.out.println("encrypted: " + new String(textencrypted));\n\n } catch (Exception ex) {\n Logger.getLogger(Aes.class.getName()).log(Level.SEVERE, null, ex);\n }\n }\n\n}\n\nRun Code Online (Sandbox Code Playgroud)\nCipher desCipher = Cipher.getInstance("AES");这里没有定义加密模式。我发现当模式未定义时它使用AES/ECB/PKCS5Padding. 加密期间也不使用 IV。
我正在将 java android 应用程序迁移到 flutter。服务器上的数据使用上述 java 代码进行加密。现在我无法更改服务器中所有正在使用的数据。我必须在 flutter 中解密它才能在 flutter 应用程序中显示数据。
\n我正在使用encrypt: ^4.1.0包在 dart 中进行解密。
\n Encrypted encryptedText = Encrypted.fromUtf8(\'\xc3\x9f\xc3\x88\xc2\xb68)\\\xc5\x93\xc3\xa57\xc2\xa3\');\n final key = Key.fromUtf8(\'1234567890123456\');\n final iv = IV.fromLength(16);\n\n final encrypter = Encrypter(AES(key, mode: AESMode.ecb));\n\n final decrypted = encrypter.decrypt(encryptedText, iv: iv);\n\n print(decrypted); \nRun Code Online (Sandbox Code Playgroud)\n但这段代码给出错误如下
\nE/flutter (18070): [ERROR:flutter/lib/ui/ui_dart_state.cc(171)] Unhandled Exception: Invalid argument(s): Input data length must be a multiple of cipher\'s block size\nE/flutter (18070): #0 PaddedBlockCipherImpl.process (package:pointycastle/padded_block_cipher/padded_block_cipher_impl.dart:60:9)\nE/flutter (18070): #1 AES.decrypt (package:encrypt/src/algorithms/aes.dart:55:22)\nE/flutter (18070): #2 Encrypter.decryptBytes (package:encrypt/src/encrypter.dart:25:17)\nE/flutter (18070): #3 Encrypter.decrypt (package:encrypt/src/encrypter.dart:31:17)\nE/flutter (18070): #4 _MyHomePageState.sha1 (package:flutter_decrypt_video/main.dart:196:33)\nE/flutter (18070): #5 _MyHomePageState.build (package:flutter_decrypt_video/main.dart:85:5)\nE/flutter (18070): #6 StatefulElement.build (package:flutter/src/widgets/framework.dart:4681:28)\nE/flutter (18070): #7 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4564:15)\nE/flutter (18070): #8 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4737:11)\nE/flutter (18070): #9 Element.rebuild (package:flutter/src/widgets/framework.dart:4280:5)\nE/flutter (18070): #10 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:4543:5)\nE/flutter (18070): #11 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:4728:11)\nE/flutter (18070): #12 ComponentElement.mount (package:flutter/src/widgets/framework.dart:4538:5)\nE/flutter (18070): #13 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3508:14)\nE/flutter (18070): #14 Element.updateChild (package:flutter/src/widgets/framework.dart:3266:18)\nE/flutter (18070): #15 SingleChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:5892:14)\nE/flutter (18070): #16 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3508:14)\nE/flutter (18070): #17 Element.updateChild (package:flutter/src/widgets/framework.dart:3266:18)\nE/flutter (18070): #18 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4589:16)\nE/flutter (18070): #19 Element.rebuild (package:flutter/src/widgets/framework.dart:4280:5)\nE/flutter (18070): #20 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:4543:5)\nE/flutter (18070): #21 ComponentElement.mount (package:flutter/src/widgets/framework.dart:4538:5)\nE/flutter (18070): #22 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3508:14)\nE/flutter (18070): #23 Element.updateChild (package:flutter/src/widgets/framework.dart:3266:18)\nE/flutter (18070): #24 SingleChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:5892:14)\nE/flutter (18070): #25 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3508:14)\nE/flutter (18070): #26 Element.updateChild (package:flutter/src/widgets/framework.dart:3266:18)\nE/flutter (18070): #27 SingleChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:5892:14)\nE/flutter (18070): #28 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3508:14)\nE/flutter (18070): #29 Element.updateChild (package:flutter/src/widgets/framework.dart:3266:18)\nE/flutter (18070): #30 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4589:16)\nE/flutter (18070): #31 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4737:11)\nE/flutter (18070): #32 Element.rebuild (package:flutter/src/widgets/framework.dart:4280:5)\nE/flutter (18070): #33 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:4543:5)\nE/flutter (18070): #34 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:4728:11)\nE/flutter (18070): #35 ComponentElement.mount (package:flutter/src/widgets/framework.dart:4538:5)\nE/flutter (18070): #36 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3508:14)\nE/flutter (18070): #37 Element.updateChild (package:flutter/src/widgets/framework.dart:3266:18)\nE/flutter (18070): #38 SingleChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:5892:14)\nE/flutter (18070): #39 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3508:14)\nE/flutter (18070): #40 Element.updateChild (package:flutter/src/widgets/framework.dart:3266:18)\nE/flutter (18070): #41 SingleChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:5892:14)\nE/flutter (18070): #42 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3508:14)\nE/flutter (18070): #43 Element.updateChild (package:flutter/src/widgets/framework.dart:3266:18)\nE/flutter (18070): #44 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4589:16)\nE/flutter (18070): #45 StatefulElement.performRebuild (package:flutter/src/widgets/fram\n\nRun Code Online (Sandbox Code Playgroud)\n如果有人知道如何做到这一点,请留下您的答案。
\n在用于加密的java代码中,使用SHA-1哈希算法来获取160位密钥,然后使用前128位进行加密,这可能会导致任何问题吗?
\n如果有人知道任何其他可以解决我的问题的软件包,请告诉我。
\n如果有人想要任何进一步的信息,请告诉我。
\n提前致谢 !!
\n在 Java 代码中,使用字符集编码(如 UTF-8)将密文转换为字符串。这通常会损坏数据。这里应该使用像base64这样的二进制到文本的编码。
问题中发布的 Java 代码提供了以下更改:
import java.util.Base64;
...
Cipher desCipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
...
String plainText = "The quick brown fox jumps over the lazy dog";
...
System.out.println("encrypted: " + Base64.getEncoder().encodeToString(textencrypted));
...
Run Code Online (Sandbox Code Playgroud)
以下 Base64 编码的密文:
encrypted: Mj48sRIlEidcVHVHIw8i8PPXUQiZB3toykI7ODbzXvbrFyOO957Euy0mzgfbVGVF
Run Code Online (Sandbox Code Playgroud)
可以使用Pointy Castle包和以下 Dart 代码来解密该密文:
import 'dart:convert';
import 'dart:typed_data';
import 'package:pointycastle/api.dart';
import 'package:pointycastle/block/aes_fast.dart';
import 'package:pointycastle/block/modes/ecb.dart';
import 'package:pointycastle/padded_block_cipher/padded_block_cipher_impl.dart';
import 'package:pointycastle/paddings/pkcs7.dart';
...
Digest sha1 = Digest("SHA-1");
Uint8List key = sha1.process(utf8.encode('1234567890123456')).sublist(0, 16);
Uint8List ciphertext = base64.decode('Mj48sRIlEidcVHVHIw8i8PPXUQiZB3toykI7ODbzXvbrFyOO957Euy0mzgfbVGVF');
ECBBlockCipher cipher = ECBBlockCipher(AESFastEngine());
PaddedBlockCipher paddedCipher = new PaddedBlockCipherImpl(new PKCS7Padding(), cipher);
PaddedBlockCipherParameters<CipherParameters, CipherParameters> paddingParams = new PaddedBlockCipherParameters(KeyParameter(key), null);
paddedCipher.init(false, paddingParams);
Uint8List plainText = paddedCipher.process(ciphertext);
print(utf8.decode(plainText));
Run Code Online (Sandbox Code Playgroud)
请注意以下几点: ECB 是一种不安全模式。更安全的是 CBC(请参阅此处的 dart 示例)或 GCM,后者允许加密和数据身份验证。此外,使用 SHA-1 从密码派生密钥也是不安全的。这里应该使用可靠的密钥导出函数,例如PBKDF2。
编辑:
将密文转换为具有 UTF-8 等字符集的字符串会损坏数据。你可以在 Stackoverflow 上找到很多帖子,例如这篇文章,它详细解释了这个问题。这意味着如果使用 UTF-8 转换密文,您问题中发布的 Java 代码将无法可靠地工作。
但是,有些字符集(例如 ISO-8859-1)不会损坏数据。服务器上可能使用这样的字符集。这无法从发布的代码中确定,因为在解码期间(即在new String(textencrypted))中没有指定字符集,因此应用了相应平台的默认字符集,请参见此处。因此,要检查这种可能性,您必须确定服务器上使用的默认字符集。
分析使用哪种编码的另一种方法是检查(或发布)用于解密服务器创建的密文的代码。
最可靠的是使用专门将二进制数据转换为字符串的编码,即所谓的二进制到文本编码,例如 Base64,请参阅此处,这就是我在发布的示例中使用 Base64 的原因。
您可以使用以下 Java 代码验证使用 UTF-8 或 ISO-8859-1 转换的效果。上面发布的示例中的数据用作密文:
convertDataWith(StandardCharsets.UTF_8);
convertDataWith(StandardCharsets.ISO_8859_1);
...
private static void convertDataWith(Charset charset) {
String ciphertextBeforeB64 = "Mj48sRIlEidcVHVHIw8i8PPXUQiZB3toykI7ODbzXvbrFyOO957Euy0mzgfbVGVF"; // Data from posted example
byte[] ciphertextBefore = Base64.getDecoder().decode(ciphertextBeforeB64);
String ciphertextCharset = new String(ciphertextBefore, charset); // Convert to String with specified charset
byte[] ciphertextAfter = ciphertextCharset.getBytes(charset); // Convert from String with specified charset
String ciphertextAfterB64 = Base64.getEncoder().encodeToString(ciphertextAfter);
System.out.println("Ciphertext BEFORE conversion: " + ciphertextBeforeB64);
System.out.println("Ciphertext AFTER conversion: " + ciphertextAfterB64);
}
Run Code Online (Sandbox Code Playgroud)
输出:
import java.util.Base64;
...
Cipher desCipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
...
String plainText = "The quick brown fox jumps over the lazy dog";
...
System.out.println("encrypted: " + Base64.getEncoder().encodeToString(textencrypted));
...
Run Code Online (Sandbox Code Playgroud)
如上所述,UTF-8 会损坏数据。
| 归档时间: |
|
| 查看次数: |
2195 次 |
| 最近记录: |