Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter Secure Storage Platform Exception

I'm using flutter secure storage (^5.0.2) to save tokens but I'm getting the following error when storage.write() is called on an emulator (I'm using Pixel 5 API 30) whereas when I use it on my physical device (Honor 8x) it's working well :

PlatformException (PlatformException(Exception encountered, write, java.lang.NullPointerException: Attempt to invoke interface method 'byte[] com.it_nomads.fluttersecurestorage.ciphers.StorageCipher.encrypt(byte[])' on a null object reference
    at com.it_nomads.fluttersecurestorage.FlutterSecureStoragePlugin.write(FlutterSecureStoragePlugin.java:202)
    at com.it_nomads.fluttersecurestorage.FlutterSecureStoragePlugin.access$300(FlutterSecureStoragePlugin.java:37)
    at com.it_nomads.fluttersecurestorage.FlutterSecureStoragePlugin$MethodRunner.run(FlutterSecureStoragePlugin.java:289)
    at android.os.Handler.handleCallback(Handler.java:938)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:223)
    at android.os.HandlerThread.run(HandlerThread.java:67)
, null))

Here is the output of the debug :

W/KeyStore( 2975): KeyStore exception
W/KeyStore( 2975): android.os.ServiceSpecificException:  (code 7)
W/KeyStore( 2975):  at android.os.Parcel.createExceptionOrNull(Parcel.java:2387)
W/KeyStore( 2975):  at android.os.Parcel.createException(Parcel.java:2357)
W/KeyStore( 2975):  at android.os.Parcel.readException(Parcel.java:2340)
W/KeyStore( 2975):  at android.os.Parcel.readException(Parcel.java:2282)
W/KeyStore( 2975):  at android.security.keystore.IKeystoreService$Stub$Proxy.get(IKeystoreService.java:988)
W/KeyStore( 2975):  at android.security.KeyStore.get(KeyStore.java:233)
W/KeyStore( 2975):  at android.security.KeyStore.get(KeyStore.java:222)
W/KeyStore( 2975):  at android.security.keystore.AndroidKeyStoreSpi.engineGetCertificate(AndroidKeyStoreSpi.java:165)
W/KeyStore( 2975):  at java.security.KeyStore.getCertificate(KeyStore.java:1120)
W/KeyStore( 2975):  at com.it_nomads.fluttersecurestorage.ciphers.RSACipher18Implementation.getPublicKey(RSACipher18Implementation.java:90)
W/KeyStore( 2975):  at com.it_nomads.fluttersecurestorage.ciphers.RSACipher18Implementation.wrap(RSACipher18Implementation.java:39)
W/KeyStore( 2975):  at com.it_nomads.fluttersecurestorage.ciphers.StorageCipher18Implementation.<init>(StorageCipher18Implementation.java:52)
W/KeyStore( 2975):  at com.it_nomads.fluttersecurestorage.FlutterSecureStoragePlugin.ensureInitialized(FlutterSecureStoragePlugin.java:95)
W/KeyStore( 2975):  at com.it_nomads.fluttersecurestorage.FlutterSecureStoragePlugin.access$100(FlutterSecureStoragePlugin.java:37)
W/KeyStore( 2975):  at com.it_nomads.fluttersecurestorage.FlutterSecureStoragePlugin$MethodRunner.run(FlutterSecureStoragePlugin.java:284)
W/KeyStore( 2975):  at android.os.Handler.handleCallback(Handler.java:938)
W/KeyStore( 2975):  at android.os.Handler.dispatchMessage(Handler.java:99)
W/KeyStore( 2975):  at android.os.Looper.loop(Looper.java:223)
W/KeyStore( 2975):  at android.os.HandlerThread.run(HandlerThread.java:67)
E/FlutterSecureStoragePl( 2975): StorageCipher initialization failed
E/FlutterSecureStoragePl( 2975): java.lang.Exception: No certificate found under alias: com.example.applielikya.FlutterSecureStoragePluginKey
E/FlutterSecureStoragePl( 2975):    at com.it_nomads.fluttersecurestorage.ciphers.RSACipher18Implementation.getPublicKey(RSACipher18Implementation.java:92)
E/FlutterSecureStoragePl( 2975):    at com.it_nomads.fluttersecurestorage.ciphers.RSACipher18Implementation.wrap(RSACipher18Implementation.java:39)
E/FlutterSecureStoragePl( 2975):    at com.it_nomads.fluttersecurestorage.ciphers.StorageCipher18Implementation.<init>(StorageCipher18Implementation.java:52)
E/FlutterSecureStoragePl( 2975):    at com.it_nomads.fluttersecurestorage.FlutterSecureStoragePlugin.ensureInitialized(FlutterSecureStoragePlugin.java:95)
E/FlutterSecureStoragePl( 2975):    at com.it_nomads.fluttersecurestorage.FlutterSecureStoragePlugin.access$100(FlutterSecureStoragePlugin.java:37)
E/FlutterSecureStoragePl( 2975):    at com.it_nomads.fluttersecurestorage.FlutterSecureStoragePlugin$MethodRunner.run(FlutterSecureStoragePlugin.java:284)
E/FlutterSecureStoragePl( 2975):    at android.os.Handler.handleCallback(Handler.java:938)
E/FlutterSecureStoragePl( 2975):    at android.os.Handler.dispatchMessage(Handler.java:99)
E/FlutterSecureStoragePl( 2975):    at android.os.Looper.loop(Looper.java:223)
E/FlutterSecureStoragePl( 2975):    at android.os.HandlerThread.run(HandlerThread.java:67)

I don't know if it could be related, but I have min Sdk 19 in my code, due to some packages needing this version.

I need this to start both my physical device and an emulator on Vscode with two different accounts in my app (an admin and an user) to check the transmission of notifications from one to another, if another way to achieve that exists I'd also be up to know.

This is the code :

import 'package:applielikya/models/login_response.dart';
import 'package:applielikya/models/user.dart';
import 'package:applielikya/services/auth/login.dart';
import 'package:applielikya/views/homepage.dart';
import 'package:applielikya/widgets/createRoute.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:flutter/material.dart';

class LoginPage extends StatefulWidget {
  const LoginPage({Key? key}) : super(key: key);

  @override
  State<LoginPage> createState() => LoginPageState();
}

enum ButtonState { init, loading, done }

class LoginPageState extends State<LoginPage> {
  final Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
  final FlutterSecureStorage storage = const FlutterSecureStorage();
  ButtonState _state = ButtonState.init;
  bool _passwordVisible = false;
  final TextEditingController _usernameController = TextEditingController(text: "kentay");
  final TextEditingController _passwordController = TextEditingController(text: "kentay");
  bool _isAuth = false;
  String _responseMessage = "";

  void saveToken(SuccessResponse response) async {
    await storage.write(key: "accessToken", value: response.accessToken);
    await storage.write(key: "refreshToken", value: response.refreshToken);
  }

  void saveUser(UserResponse user) async {
    final SharedPreferences prefs = await _prefs;
    prefs.setString('username', user.username as String);
    prefs.setInt('id', user.id as int);
    prefs.setString('role', user.role as String);
    if (user.role == "prof") {
      prefs.setString("firstname", user.firstname!);
      prefs.setString("lastname", user.lastname!);
      prefs.setString("email", user.email!);
    }
  }

  submitLogin() async {
    setState(() => _state = ButtonState.loading);
    final response = await login(
      UserRequest(username : _usernameController.text, password: _passwordController.text)
    );

    setState(() {
      _isAuth = response.auth;
      _state = ButtonState.done;
    });

    if (response is SuccessResponse) {
      saveToken(response);
      saveUser(response.user);
      setState(() => _state = ButtonState.init);
      Navigator.of(context).push(
        createRoute(
          const MyHomePage(),
          const Offset(0.0, 1.0),
          Offset.zero,
          Curves.easeInCirc
        )
      );
    } else {
      if (response is ErrorResponse) {
        setState(() => _responseMessage = response.message);
      }
    }
  }
like image 766
KenTay7 Avatar asked Nov 02 '25 01:11

KenTay7


1 Answers

i think the isseus was form arecent update. just add the option below for android.

final FlutterSecureStorage storage = const FlutterSecureStorage(
    aOptions: AndroidOptions(
      encryptedSharedPreferences: true,
    ),
  );
like image 98
Astro Avatar answered Nov 03 '25 17:11

Astro



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!