Skip to content

Commit 469b54a

Browse files
authored
Merge pull request #449 from DanXi-Dev/upgrade-secure-storage
Upgrade secure storage and fix regression issue introduced by migration logic
2 parents 56c29c8 + 33b4edb commit 469b54a

File tree

4 files changed

+65
-29
lines changed

4 files changed

+65
-29
lines changed

lib/page/subpage_settings.dart

+5-6
Original file line numberDiff line numberDiff line change
@@ -237,8 +237,7 @@ class SettingsSubpageState extends PlatformSubpageState<SettingsSubpage> {
237237
"https://github.com/50431040/device_identity"),
238238
LicenseItem("tutorial_coach_mark", LICENSE_MIT,
239239
"https://github.com/RafaelBarbosatec/tutorial_coach_mark"),
240-
LicenseItem("toml", LICENSE_MIT,
241-
"https://github.com/just95/toml.dart"),
240+
LicenseItem("toml", LICENSE_MIT, "https://github.com/just95/toml.dart"),
242241
LicenseItem("pub_semver", LICENSE_BSD_3_0_CLAUSE,
243242
"https://github.com/dart-lang/pub_semver"),
244243
];
@@ -252,10 +251,10 @@ class SettingsSubpageState extends PlatformSubpageState<SettingsSubpage> {
252251
await ForumRepository.getInstance().logout();
253252
} finally {
254253
progressDialog.dismiss(showAnim: false);
255-
SettingsProvider.getInstance()
256-
.preferences
257-
?.clear()
258-
.then((value) => FlutterApp.restartApp(context));
254+
await SettingsProvider.getInstance().preferences?.clear();
255+
if (mounted) {
256+
FlutterApp.restartApp(context);
257+
}
259258
}
260259
}
261260

lib/util/shared_preferences.dart

+44-4
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
* along with thFlutterSecureStorageis program. If not, see <https://www.gnu.org/licenses/>.
1616
*/
1717

18+
import 'package:encrypt/encrypt.dart';
19+
import 'dart:async';
1820
import 'dart:convert';
1921
import 'dart:math';
2022

@@ -35,7 +37,9 @@ class XSharedPreferences {
3537
final FlutterSecureStorage _keyStore;
3638
late final EncryptedSharedPreferences _preferences;
3739

38-
XSharedPreferences._() : _keyStore = const FlutterSecureStorage();
40+
XSharedPreferences._() : _keyStore = const FlutterSecureStorage(
41+
wOptions: WindowsOptions(useBackwardCompatibility: true),
42+
);
3943

4044
static XSharedPreferences? _instance;
4145

@@ -67,7 +71,7 @@ class XSharedPreferences {
6771
}
6872
String key = (await _instance!._keyStore.read(key: KEY_CIPHER))!;
6973
// initialize the encrypted preferences.
70-
await EncryptedSharedPreferences.initialize(key);
74+
await EncryptedSharedPreferences.initialize(key, encryptor: LegacyAESEncryptor());
7175
_instance!._preferences = EncryptedSharedPreferences.getInstance();
7276
// migrate the data from [SharedPreferences] to [EncryptedSharedPreferences]
7377
// if the data has not been flagged as migrated.
@@ -97,11 +101,18 @@ class XSharedPreferences {
97101

98102
// Proxy methods for [EncryptedSharedPreferences]
99103

100-
Future<bool> clear() => _preferences.clear();
104+
Future<bool> clear() async {
105+
bool success = await _preferences.clear();
106+
if (success) {
107+
// mark the data as migrated after clearing. Or the data written after clearing will be re-migrated.
108+
await _instance!.setBool(KEY_MIGRATED, true);
109+
}
110+
return success;
111+
}
101112

102113
Future<bool> remove(String key) => _preferences.remove(key);
103114

104-
Future<Set<String>> getKeys() => _preferences.getKeys();
115+
FutureOr<Set<String>> getKeys() => _preferences.getKeys();
105116

106117
Future<bool> setString(String dataKey, String? dataValue) =>
107118
_preferences.setString(dataKey, dataValue);
@@ -141,3 +152,32 @@ class XSharedPreferences {
141152
}
142153
}
143154
}
155+
156+
157+
/// @w568w (2024-11-26):
158+
/// encrypt_shared_preferences quietly changed the default AES Encryptor to use SIC mode from CBC mode.
159+
/// This is obviously a breaking change, but it is mentioned nowhere in the changelog. Average noob developer.
160+
///
161+
/// So this class is an implementation of the legacy AES Encryptor.
162+
class LegacyAESEncryptor extends IEncryptor{
163+
@override
164+
String encrypt(String key, String plainText) {
165+
assert(key.length == 16);
166+
final cipherKey = Key.fromUtf8(key);
167+
final encryptService = Encrypter(AES(cipherKey, mode: AESMode.cbc));
168+
final initVector = IV.fromUtf8(key);
169+
170+
Encrypted encryptedData = encryptService.encrypt(plainText, iv: initVector);
171+
return encryptedData.base64;
172+
}
173+
174+
@override
175+
String decrypt(String key, String encryptedData) {
176+
assert(key.length == 16);
177+
final cipherKey = Key.fromUtf8(key);
178+
final encryptService = Encrypter(AES(cipherKey, mode: AESMode.cbc));
179+
final initVector = IV.fromUtf8(key);
180+
181+
return encryptService.decrypt(Encrypted.fromBase64(encryptedData), iv: initVector);
182+
}
183+
}

pubspec.lock

+13-13
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ packages:
431431
source: hosted
432432
version: "2.0.0"
433433
encrypt:
434-
dependency: transitive
434+
dependency: "direct main"
435435
description:
436436
name: encrypt
437437
sha256: "62d9aa4670cc2a8798bab89b39fc71b6dfbacf615de6cf5001fb39f7e4a996a2"
@@ -442,10 +442,10 @@ packages:
442442
dependency: "direct main"
443443
description:
444444
name: encrypt_shared_preferences
445-
sha256: "83324f4350442d4b19994b22e5d87766eed9ee87b8211626b3b0d84bce1e98b9"
445+
sha256: "6d9496f5873ab38d8cbea52dfeafc5e361a61193cc4d9f2da5f0f092b5ddab1a"
446446
url: "https://pub.dev"
447447
source: hosted
448-
version: "0.3.8"
448+
version: "0.8.1"
449449
equatable:
450450
dependency: transitive
451451
description:
@@ -498,10 +498,10 @@ packages:
498498
dependency: transitive
499499
description:
500500
name: file_selector_linux
501-
sha256: b2b91daf8a68ecfa4a01b778a6f52edef9b14ecd506e771488ea0f2e0784198b
501+
sha256: "54cbbd957e1156d29548c7d9b9ec0c0ebb6de0a90452198683a7d23aed617a33"
502502
url: "https://pub.dev"
503503
source: hosted
504-
version: "0.9.3+1"
504+
version: "0.9.3+2"
505505
file_selector_macos:
506506
dependency: transitive
507507
description:
@@ -789,10 +789,10 @@ packages:
789789
dependency: "direct main"
790790
description:
791791
name: flutter_secure_storage
792-
sha256: "22dbf16f23a4bcf9d35e51be1c84ad5bb6f627750565edd70dab70f3ff5fff8f"
792+
sha256: "165164745e6afb5c0e3e3fcc72a012fb9e58496fb26ffb92cf22e16a821e85d0"
793793
url: "https://pub.dev"
794794
source: hosted
795-
version: "8.1.0"
795+
version: "9.2.2"
796796
flutter_secure_storage_linux:
797797
dependency: transitive
798798
description:
@@ -829,10 +829,10 @@ packages:
829829
dependency: transitive
830830
description:
831831
name: flutter_secure_storage_windows
832-
sha256: "38f9501c7cb6f38961ef0e1eacacee2b2d4715c63cc83fe56449c4d3d0b47255"
832+
sha256: b20b07cb5ed4ed74fc567b78a72936203f587eba460af1df11281c9326cd3709
833833
url: "https://pub.dev"
834834
source: hosted
835-
version: "2.1.1"
835+
version: "3.1.2"
836836
flutter_svg:
837837
dependency: transitive
838838
description:
@@ -1378,10 +1378,10 @@ packages:
13781378
dependency: transitive
13791379
description:
13801380
name: path_provider_android
1381-
sha256: c464428172cb986b758c6d1724c603097febb8fb855aa265aeecc9280c294d4a
1381+
sha256: "8c4967f8b7cb46dc914e178daa29813d83ae502e0529d7b0478330616a691ef7"
13821382
url: "https://pub.dev"
13831383
source: hosted
1384-
version: "2.2.12"
1384+
version: "2.2.14"
13851385
path_provider_foundation:
13861386
dependency: transitive
13871387
description:
@@ -2152,10 +2152,10 @@ packages:
21522152
dependency: transitive
21532153
description:
21542154
name: vector_graphics_compiler
2155-
sha256: ab9ff38fc771e9ee1139320adbe3d18a60327370c218c60752068ebee4b49ab1
2155+
sha256: "1b4b9e706a10294258727674a340ae0d6e64a7231980f9f9a3d12e4b42407aad"
21562156
url: "https://pub.dev"
21572157
source: hosted
2158-
version: "1.1.15"
2158+
version: "1.1.16"
21592159
vector_math:
21602160
dependency: transitive
21612161
description:

pubspec.yaml

+3-6
Original file line numberDiff line numberDiff line change
@@ -91,12 +91,9 @@ dependencies:
9191
git:
9292
url: https://github.com/w568w/receive_intent.git
9393

94-
# These two libraries are used to encrypt shared preferences.
95-
# They introduced breaking changes in their latest versions,
96-
# making them unable to read the old encrypted data.
97-
# Therefore, we have to pin them at the these versions.
98-
flutter_secure_storage: ^8.0.0
99-
encrypt_shared_preferences: ^0.3.5
94+
flutter_secure_storage: ^9.0.0
95+
encrypt_shared_preferences: ^0.8.1
96+
encrypt: any
10097
device_identity: ^1.0.0
10198
tutorial_coach_mark: ^1.2.9
10299
flutter_platform_widgets: ^7.0.0

0 commit comments

Comments
 (0)