当前位置: 首页 > 知识库问答 >
问题:

如何在flutter中使用AES-256加密字符串,以便它使用openSSL在Web上解密

潘意
2023-03-14

我尝试在dart中使用encrypt library加密一个字符串,它工作得很好,除了当我在在线AES解密器中尝试生成的加密字符串和密钥以及iv时,它从未成功解密。我想将加密的数据发送到服务器,然后需要在服务器和移动设备上解密这些数据,但我找不到任何解决方案。我的服务器使用PHP和openSSl,除了这个库,我在flutter中找不到任何OpenSSL库,但它有0个文档。

这是我使用的示例代码

尝试1:

final plainText = 'My Phone number is: 1234567890';
final key = encrypt.Key.fromLength(32);
final iv = encrypt.IV.fromLength(16);
final encrypter = encrypt.Encrypter(encrypt.AES(key));

final encrypted = encrypter.encrypt(plainText, iv: iv);
final decrypted = encrypter.decrypt(encrypted, iv: iv);

print(key.base64); // prints AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
print(iv.base64); // prints AAAAAAAAAAAAAAAAAAAAAA==
print(encrypted.base64); // prints kezgKMov5+yNJtd58OFSpzp8sNv2dwWNnFWDyf37cYk=

尝试2:

这次我使用了这个使用尖头城堡来创建相同数据的要点,但这次 IV 是在html" target="_blank">数组中生成的,我的服务器期望它作为 int 或字符串。

尝试3:

这一次我再次尝试使用加密,发现了一个使用cryptoJS在网络中加密数据进行解密的媒体链接。这让我想,所有AES加密库是否都不兼容?

final plainText = 'My Phone number is: 1234567890';
final newKey = Utils.CreateCryptoRandomString(32); // value is lh1uCZN4c8AFL2P4HudHV8B7dEBLzjxarZ09IrCf9cQ=
final encryptedAES = encryptAESCryptoJS(plainText, newKey);

在< code > encrypteascryptojs 函数中,我添加了打印语句来打印生成的Salt、IV和key,如下所示:

SALT = [112, 161, 85, 133, 146, 178, 232, 83]
KEY = 0IfSLn8F33SIiWlYTyT4j7n6jnNP74xNaKTivqNeksE=
IV = QCl8fNQtg+QQYTQCINV6IA==

我可以使用所有的方法轻松地在本地加密和解密,但是我如何添加支持以便加密的数据也可以在服务器上解密呢?

我试图用来解密数据的一些网站是

https://string-o-matic.com/aes-decrypt和https://www . dev glan . com/online-tools/AES-加密-解密

在添加键时都抛出了错误,在指定字段上抛出了iv

任何帮助都将不胜感激。

共有2个答案

浦毅
2023-03-14

我有同样的问题,因为在phpopenssl_decrypt与aes-256-cbc是用来解密,但在dart它不为我工作,直到我发现一个代码片段在github解决方案,这作为提出一个解决方案的基础,使其解码用php Lumen和AES openssl加密的文本,我希望它能帮助你。

// code decrypt in PHP
 $key = '**********key secred';
 $encrypted = $request->get('encrypted');
 $payload = json_decode(base64_decode($encrypted), true);
 $iv = base64_decode($payload['iv']);
 $decrypted = openssl_decrypt($payload['value'], 'aes-256-cbc', 
 base64_decode($key), 0, $iv, '');
 $response['decrypted'] = unserialize($decrypted);
 return $this->successResponse($response);

/// code decrypt in dart
 import 'dart:convert';
 import 'package:encrypt/encrypt.dart' as enc;
 import 'dart:async';
 import 'package:php_serializer/php_serializer.dart';

 Future<String> decryptInfo(String data) async {
       var encodedKey = 'FCAcEA0HBAoRGyALBQIeCAcaDxYWEQQPBxcXH****** example';
       var decoded = base64.decode(data);
      var payload = json.decode(String.fromCharCodes(decoded));
      String encodedIv = payload["iv"]?? "";
      String value = payload["value"] ?? "";
      print(decoded);
      print(payload);
      print (encodedIv);
      final key1 = enc.Key.fromBase64(encodedKey);
      final iv = enc.IV.fromBase64(encodedIv);
     final encrypter = enc.Encrypter(enc.AES(key1, mode: enc.AESMode.cbc));
     final decrypted = encrypter.decrypt(enc.Encrypted.fromBase64(value), iv: iv);
     print(phpDeserialize(decrypted));
   return decrypted;
  } 
宋望
2023-03-14

除了这个库之外,在颤振中找不到任何 openSSl 库,但它有 0 个文档。

是的,看来这是个问题。此外,我认为重要的是,无论语言实现如何,都要有人理解基础知识

我想将加密数据发送到服务器,然后需要在服务器和移动设备上解密该数据,但我找不到任何解决方案

那是TLS的任务

数据也需要加密存储,以便在后端工作的任何人都无法查看数据

只需使用相同的加密和解密参数。我看到的代码问题在于它缺少一些参数并使用默认值(默认值在不同的库中可能不同)或假设您使用不同的参数。

对称加密(特别是AES)需要定义:

  • 密钥-对于AES,它总是128、192或256位(取决于强度)。一些库对输入进行零填充或修剪以匹配所需的键长度,我认为这是一种糟糕的做法。简单地说,键需要是特定长度的字节数组

加密多个数据块时:

    < li >填充-如何填充输入以匹配加密块大小(通常为pkcs#7填充) < li >操作模式 < li>IV -请参见有关操作模式的文档,IV必须是唯一的,对于某些模式,IV需要是不可预测的(随机的)。

SALT用于从密码创建加密密钥。因此,当你看到任何盐在使用时,检查你是否提供了一个密钥或密码。密码可以有任意长度,通常由用户处理(具有较低的熵),并且有多种方法可以从密码和salt中导出密钥。

<code>var encrypted=encryptAESCryptJS(明文,“密码”)

参见源代码,< code > encrypteascryptojs 期望一个密码作为输入,然后生成一个salt并派生一个key和IV(这是OpenSSL的一个实践,但可能与其他库不兼容)。

这是一些库的问题,主要是在缺少文档时。

所有AES加密库是否相互不兼容?

AS 密码是 AES 密码。无论编程语言或平台如何,您都需要获得相同的密码,密钥,填充,IV和操作模式以进行加密和解密。有一些最常见的默认值(AES-128,CBC模式,PKCS#7填充等),但最好正确指定参数以确保。

但是这次IV是在一个数组中生成的,我的服务器希望它是一个int或string。

加密始终在字节数组之上工作。您可以将字节数组编码为 base64 或十六进制编码的字符串。

编辑:额外的安全措施

我在这个解决方案(实际上是在许多其他解决方案中)中缺少的是身份验证标签。大多数加密模式都是可延展的,可以更改密文,然后解密将成功解密为不同的明文,而不会检测到任何完整性问题。我认为使用任何 HMAC 都是必要的,但在许多实现中都缺少。

 类似资料:
  • 我是密码学的新手。我的要求是对使用openssl加密/解密的文本进行解密/加密。我们在Openssl中使用的算法是aes-256-cbc。因此,我尝试在我的应用程序中实现相同的功能。到目前为止,在谷歌搜索了很多次之后,我所能做的就是。。 我的openssl命令是 我的密钥长度是32位IV是16位 Thnx...

  • 字符串像这里一样用php加密。可以用这个用参数解密:Rijndael-256,ECB,Base64。但是我的ActionScript代码无法解密它: 更新: “它无法解密”意味着我弄错了纯文本。 在php中,明文首先由aes-256-ecb加密。然后由Base64编码。在ActionScript中,这些步骤以相反的顺序进行。 UPD2: 编码-解码测试: 在 停止后的输出是: 更新3: 它适用于P

  • 问题内容: 我有一个来自CryptoJS的加密AES-256字符串,带有密码短语。我需要用Java对其解密,但无法弄清楚该怎么做。似乎需要IV,密钥和盐来解密,就像在CryptoJS主页中一样,加密的数据已经包含所有这些内容,并且CryptoJS可以某种方式从加密的输入中解析出它们。 有人知道该怎么做吗?我已经看到了很多有关CryptoJS的示例-Java加密/解密,但大多数都使用硬编码的IV /

  • 我有一个加密的AES-256字符串从CryptoJS与密码。我需要Java解密,但不知道怎么做。似乎你需要IV、key和盐来解密,就像在CryptoJS主页一样,加密数据已经包含了所有这些数据,CryptoJS可以以某种方式将它们从加密输入中解析出来。 有人知道怎么做吗?我已经看到了很多关于CryptoJS的例子——Java加密/解密,但大多数都使用硬编码的IV/密钥,或者只是从CryptoJS端

  • 我使用以下命令加密了一个文件 openssl rand 32>test.key openssl enc-aes-256-cbc-iter 10000-pbkdf2-salt-输入test.txt-输出test.txt.enc-通过文件:test.key 我的代码 我得到的错误 我引用了以下链接 尝试使用时,仍然得到错误

  • 我只想用这3种模式测试openSSL中的AES:128192和256密钥长度,但我解密的文本与我的输入不同,我不知道为什么。此外,当我传递一个巨大的输入长度(比如1024字节)时,我的程序显示。。。我的意见总是一样的,但这并不重要,至少现在是这样。代码如下: 编辑: 当我将输出大小更改为而不是时,我得到了结果: 那么,是否有可能存在Outpus大小和IV大小的问题?它们应该有什么尺寸(AES-CB