Flutter / Dart AES-256-CBC 从 PHP 中的加密中解密

2023-11-24

任何人都可以帮助我找出使用 AES-256-CBC 在 PHP 中加密的数据的解密算法。我尝试了很多不同的方法,但我认为在尝试复制在 Dart 中重新创建 Key/IV 的方法时我搞砸了,并且不断收到异常,例如:

RangeError (end): Invalid value: Not in inclusive range 0..16:

进行加密的PHP代码(由于加密字符串由第三方提供,因此无法更改)如下:

function encrypt( $string, $encrypt=true) {
    $secret_key = 'SuperSecretKey';
    $secret_iv = 'SuperSecretBLOCK';
    $output = false;
    $encrypt_method = "AES-256-CBC";
    $key = hash( 'sha256', $secret_key );
    $iv = substr( hash( 'sha256', $secret_iv ), 0, 16 );
    if($encrypt) {
        $output = base64_encode( openssl_encrypt( $string, $encrypt_method, $key, 0, $iv ) );
    } else {
        $output = openssl_decrypt( base64_decode( $string ), $encrypt_method, $key, 0, $iv );
    }
    return $output;
}

例如,如果调用 PHP 中的加密例程来加密字符串“This is a Test!”,则结果将是:

ZHArWURDY2FkelBtSGY5c1AzdTNBZz09

我试图在 Dart 中解密的正是这个结果,但没有任何运气!

到目前为止,这是我所得到的导致上面提到的异常的原因:

import 'package:encrypt/encrypt.dart';
import 'package:crypto/crypto.dart';
import 'dart:convert' show utf8;

String extractPayload(String payload) {
      String strPwd = 'SuperSecretKey';
      String strIv = 'SuperSecretBLOCK';
      var iv = sha256.convert(utf8.encode(strIv));
      var key = sha256.convert(utf8.encode(strPwd));
      IV ivObj = IV.fromUtf8(iv.toString());
      Key keyObj = Key.fromUtf8(key.toString());
      final encrypter = Encrypter(AES(keyObj));
      final decrypted = encrypter.decrypt(Encrypted.from64(payload), iv: ivObj);
      print(decrypted);
      return decrypted;
}

有任何建议欢迎欢迎, 谢谢


PHP 代码有许多不必要的弱点,使移植变得复杂:

  • 散列时,结果以十六进制编码字符串的形式返回,不幸的是,这是默认的hash功能。将结果作为二进制数据返回会更有意义(但为此,必须将第三个参数显式设置为TRUE)。在这种情况下,以十六进制字符串形式返回有两个缺点:
  1. 由于每个字节由两个字符表示,因此SHA256的32字节哈希由64个字符表示,即64个字节。这被用作 AES-256 密钥(因为在实现过程中可能错误地假设了二进制数据),导致密钥无效,因为 AES-256 密钥的大小正好是 32 字节。 PHPsolves通过截断太长的键(太短的键用 0 值填充)来解决此问题,即仅前 32 个字节用于键。对于跨平台实现,在密钥无效的情况下显示错误消息会更有用,而不是应用任意和不透明的规则秘密生成有效密钥。
  2. 对于十六进制字符串,可以使用大写或小写字母表示数字 (a-f),具体取决于平台。如果是跨平台实现的情况,则会生成不同的密钥。这里这并不重要,因为 PHP 和 Dart 使用小写字母。
  • openssl_encrypt默认情况下对密文进行 Base64 编码,openssl_decrypt默认情况下需要 Base64 编码的密文。可以使用标志禁用此功能OPENSSL_RAW_DATA,但当前代码中并非如此。同时在加密时对密文进行了显式Base64编码,因此它是双重Base64编码的。类似地,在解密密文时,它是显式 Base64 解码的,因此它也是双重 Base64 解码的。这种冗余是没有意义的,只会不必要地增加密文并降低性能。

此外,Dart 代码假定了错误的默认值:encrypt包使用 SIC(或 CTR)作为默认模式。由于 CBC 是在 PHP 代码中指定的,因此必须在 Dart 代码中显式指定此模式。

以下 Dart 实现解密密文ZHArWURDY2FkelBtSGY5c1AzdTNBZz09:

import 'package:encrypt/encrypt.dart' as EncryptPack;
import 'package:crypto/crypto.dart' as CryptoPack;
import 'dart:convert' as ConvertPack;

String extractPayload(String payload) {
    String strPwd = "SuperSecretKey";
    String strIv = 'SuperSecretBLOCK';
    var iv = CryptoPack.sha256.convert(ConvertPack.utf8.encode(strIv)).toString().substring(0, 16);         // Consider the first 16 bytes of all 64 bytes
    var key = CryptoPack.sha256.convert(ConvertPack.utf8.encode(strPwd)).toString().substring(0, 32);       // Consider the first 32 bytes of all 64 bytes
    EncryptPack.IV ivObj = EncryptPack.IV.fromUtf8(iv);
    EncryptPack.Key keyObj = EncryptPack.Key.fromUtf8(key);
    final encrypter = EncryptPack.Encrypter(EncryptPack.AES(keyObj, mode: EncryptPack.AESMode.cbc));        // Apply CBC mode
    String firstBase64Decoding = new String.fromCharCodes(ConvertPack.base64.decode(payload));              // First Base64 decoding
    final decrypted = encrypter.decrypt(EncryptPack.Encrypted.fromBase64(firstBase64Decoding), iv: ivObj);  // Second Base64 decoding (during decryption)
    return decrypted;
}

以下测试返回明文这是一个测试!

String plaintext = extractPayload("ZHArWURDY2FkelBtSGY5c1AzdTNBZz09");
print(plaintext); // This is a Test!
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Flutter / Dart AES-256-CBC 从 PHP 中的加密中解密 的相关文章

随机推荐

  • websphere 上的字符编码问题

    我在两个应用程序服务器 websphere 8 0 0 3 中部署的应用程序存在以下问题 这些服务器具有相同的配置文件 为了确定起见 我一度导出了一个配置文件并将其导入到第三个应用程序服务器 并且我在读取和显示以 iso8859 7 编码的
  • 来自 Bloomberg 价格的 IMPORTXML 和正确的 XPath [重复]

    这个问题在这里已经有答案了 我正在尝试从彭博网站获取共同基金的价格 我尝试在 Google 表格中使用 ImportXML 函数 放入 Bloomberg 链接并复制完整的 XPath 但它总是返回 N A 这是我的功能 IMPORTXML
  • Wix修改现有的ini文件

    我试图在 Wix 中修改 ini 文件 如果它不存在 则 msi 不会完成 我该如何检查这个 我真的很想修改它 是的 我查看了其他 stackoverflow 问题 答案以及 google 我正在尝试这个
  • 模板中的 ngIf-else

    我正在尝试加载pictureA or pictureB 我的第一个解决方案是这样的 img src my picture width 180 height 80 img src default picture 但我想用if else如 AP
  • Uri.IsWellFormedUriString 需要更新吗?

    我想我可能发现了 Uri IsWellFormedUriString 方法中的错误 可能是因为它只符合RFC 2396 and RFC 2732标准而不是新的RFC 3986这使得上述两个过时了 我认为发生的情况是任何非 us ascii
  • 从 nsarray 中获取 n 个随机对象(例如 4)

    我有一个很大的 NSArray 名称 我需要从该数组中随机获取 4 条记录 名称 我该怎么做 include
  • 是否有可能在 emgucv 中找到“斑点”区域的边缘?

    我有一个看起来像这样的图像 我想找到黑暗部分的边缘 如下所示 红线是我正在寻找的 我尝试了几种方法 但没有一个有效 所以我希望有一位 emgu 大师愿意帮助我 方法一 将图像转换为灰度 去除噪音并反转 删除任何不太亮的东西 获取精明和多边形
  • startMonitoringSignificantLocationChanges 的替代方案?

    我是iPhone应用程序开发的初学者 但我正在尝试制作一个应用程序 基本上每隔一段时间更新一次您的位置 当它不在前台时 这样我就可以绘制一个人在他 她时去过的地方启动一个应用程序 我以为我可以使用 startMonitoringSignif
  • 无法获取 Gradle 包装器属性

    当我尝试导入项目时出现以下错误 无法从以下位置获取 Gradle 包装器属性 F projects Polyfills cordova platforms android gradle wrapper gradle wrapper prop
  • 如何在 Maven 中使用 BOM 文件?

    我在互联网上进行了大量研究 但没有找到任何简单的解释如何处理BOM使用 Maven 生成文件 问题是我使用 JBoss 7 1 1 并且我想将所有 JBoss 客户端 jar 包含在pom xml JBoss 有一本手册说我应该使用 BOM
  • Python 样条线或其他与 x 轴上的时间一起工作的插值?

    尝试使用非常有用的 pandas 来处理作为时间序列的数据 我现在绊倒了这样一个事实 似乎不存在可以直接对具有 DateTime 作为 x 的数据进行插值 使用样条曲线或类似方法 的库轴 我似乎总是被迫首先转换为某个浮点数 例如 1980
  • SQL Server 2005 非聚集索引死锁

    谁能帮我解决 SQL Server 2005 中的死锁问题 对于一个简单的测试 我有一个表 Book 它有一个主键 id 和一个列名 该主键的默认索引是非聚集的 当两个会话同时运行时就会发生死锁 活动监视器显示第一个会话 step 1 使用
  • Heroku 和 node-cron?

    所以我知道 Heroku 的免费测功机在没有任何流量时会 放松 这会如何影响我使用 node cron 模块实现的 cron 作业 当您的空闲测功机处于睡眠状态时 由node cron 安排的作业将不会运行 作为替代方案 您可以使用Hero
  • json.dump() 是否附加到文件?

    我在使用 json dump 时遇到一些意外行为 我正在创建一个文件results 空 然后在代码中使用它 如下所示 with open results r as fp temp try file not empty load existi
  • Double 值返回 0 [重复]

    这个问题在这里已经有答案了 这是一个例子 Double d 1 3 System out println d 这会返回 0 而不是 0 33333 它应该是这样 有人知道吗 那是因为1 and 3被视为integers当你没有另外指定时 所
  • Spray.io:无法编译测试规范

    我有以下服务 trait PingService extends MyHttpService val pingRoutes path ping get complete message gt pong MyHttpService是一个扩展的
  • 使用 OpenCV 在斑点内创建矩形

    输入图像 输出图像 我的图像中有几个彩色斑点 我试图在每种颜色的最大斑点内创建矩形 或正方形 这似乎更容易 我发现了如何创建一个包围单个最大斑点的矩形 的答案 但我不确定如何找到一个适合在斑点内的正方形 它不一定是最大的 它只需要大于某个区
  • ModuleNotFoundError:pip 安装后没有名为 的模块

    我在 python 包分发中迈出了第一步 不幸的是 我有ModuleNotFoundError从 pip 安装成功后 我的目录布局非常简单 maindir setup py pysoft init py main py pylib py m
  • Python/Django shell 无法启动

    Django 的一大特色是您可以打开 python 解释器设置以用于您的项目 这可用于分析数据库中的对象 并允许在您的项目上执行任何 python 命令 我发现它对于 Django 开发至关重要 使用以下命令在项目目录中调用它 python
  • Flutter / Dart AES-256-CBC 从 PHP 中的加密中解密

    任何人都可以帮助我找出使用 AES 256 CBC 在 PHP 中加密的数据的解密算法 我尝试了很多不同的方法 但我认为在尝试复制在 Dart 中重新创建 Key IV 的方法时我搞砸了 并且不断收到异常 例如 RangeError end