Dart 中使用 DES 和 3DES 加解密

学习的一个重要阶段是模仿。老夫学习 flutter 从移植一个现有的几乎已经被废弃的 Android 端产品开始。其中网络报文传输时有用到 3DES。dart 似乎没有官方的现成实现,在 pub.dev(的国内镜像站 https://pub.flutter-io.cn)里搜索,会有若干个插件,经过对代码风格以及 API 的肉眼考察后选择了 tripledes-dart,在 pubspec.yaml 里添加 tripledes: 2.1.0 的依赖即可。

最开头犯了个很低级的错误(尽管我经常和人说,错误其实是不分低级和高级的),照着例子把引擎初始化成了 DESEngine 而不是本应当的 TripleDESEngine,导致结果一直有问题,后来才发现、改正。改正后有个奇怪的情况,打印出的报文中,中文部分都是乱码。

尽管在字符编码方面的知识,老夫自忖可以算是专家,但是一门编程语言中,对字符串如何进行存储可以有自己的独有设计。原始的产品,报文发出的服务端应该是 Java 实现的,Android 端接收到以后也是 Java 代码进行逆向处理,因而问题并不明显。而 Dart 显然有自己的特色。在这门语言里(刚学两三天),迄今还没有看到像 byte[] 或者 ByteArray 这样的数据类型,最接近的是 Uint8List,它和 List<int> 以及 String 数据类型的相互转换正是需要了解的核心。

别不赘述,本文最后将附上的是本人对 tripledes-dart 项目在 GitHub 上一个长达一年无人回复的问题“Error when encrypt, decrypt text UTF8”的答案,见下,各位一看便明了。

有问题的代码片段为:

问题的根源在于两个方面:1. Dart 的 Stiring 对象中,字符是 UTF-16 格式组织的;2. tripledes-dart 在其按块处理的过程中,把每个字符的每个字节均按照 LATIN-1 进行处理。修订后的功能正常的代码其实仅需增加两行,为了读者复制以及测试的便利,以下仍然附上 main 函数的完整代码块(其余部分均不需任何改动)。因此到底多了哪两行,请自行辨识。

善哉。老夫这也算做了一件善事。

发表评论

电子邮件地址不会被公开。 必填项已用*标注