Coder Social home page Coder Social logo

securestorage's Introduction

Secure Storage Plugin for Xamarin and Windows Apps (iPhone, Android, UWP, Mac, Tizen)

The plugin can be used to Securely store sensitive data strings such as password, session token, credit card number etc. This plugin securely stores the strings across sessions on iOS, Android, UWP, Mac and Tizen apps. Ver 2.0.0 is now compatible with .net standard.

The supported platforms include:

  • iOS Unified
  • Android
  • UWP
  • MacOS (OSX)
  • Tizen

It has easy to use API of key-value pairs. The pairs are saved using platform specific encryption mechanism. It has no dependencies on any packages (including Xamarin.Forms, MVVMCross.). And can be used by any Xamarin or UWP or Tizen app. It is open source.

Note

If your app fails to save values in iOS 10 Simulator, open the Entitlements.plist file and make sure that "Enable Keychain Access Groups" is checked. Also ensure that in Project->Options->iOS Bundle Signing, the Entitlements.plist is selected in Custom Entitlements for iPhoneSimulator platform. This happens only in iOS 10 Simulator due to https://forums.xamarin.com/discussion/77760/ios-10-keychain

Usage

It provides 4 methods.

SetValue - Stores the key and value.

CrossSecureStorage.Current.SetValue(“SessionToken”, “1234567890”);

GetValue - Returns the value for the given key. If not found, returns default value.

var sessionToken = CrossSecureStorage.Current.GetValue (“SessionToken”);

DeleteKey - Deletes the given key and corresponding value from the storage.

CrossSecureStorage.Current.DeleteKey(“SessionToken”);

HasKey - Checks if the given key exists in the storage.

var exists = CrossSecureStorage.Current.HasKey (“SessionToken”);

In the UWP Apps, the data is stored in the password vault. It has a built in limit of 10 values per app.

The plugin can be found here:

https://www.nuget.org/packages/sameerIOTApps.Plugin.SecureStorage/

The sample apps on GitHub show how to use it in Xamarin and in Tizen Apps.

Blog: https://sameerkapps.wordpress.com/2016/02/01/secure-storage-plugin-for-xamarin/

Breaking Changes in 2.5.0

  • iOS - The KeyChain access level is now set at AfterFirstUnlock as default. This will let app set the values in the background mode. As a result, the keys stored using the earlier versions will not be accessible with this version. To maintain backward compatibility, add a line to AppDelegate as follows:
SecureStorageImplementation.DefaultAccessible = Security.SecAccessible.Invalid;
  • Android - This version provides two storage types:
  1. Android Key Store - This is now the default mechanism for storage. Android recommends using it as it prevents other apps from using the file. ref: https://developer.android.com/training/articles/keystore#WhichShouldIUse This is not compatible with the currently stored values.

  2. Password Protected File - This is provided for the backward compatibility. If you want to use this mode, set it as follows:

SecureStorageImplementation.StorageType = StorageTypes.PasswordProtectedFile;

By default the password for storage is the hardware serial number. So it is unique per device. Should you want to choose your password, it can be done as follows

ProtectedFileImplementation.StoragePassword = "YourPassword";

Make sure that you obfuscate the app so the password is not reverse engineered.

Changes in 2.0.0

  • Abstraction Layer - Now compatible with .net standard

  • iOS - No special changes

  • Android - Hardware serial number is the default password

  • UWP - New platform in 2.0.0. It has the following limitations.

      UWP Password vault has limitation of 10 values per app
      The value cannot be set as null or empty string. (Delete the key instead.)
    
  • Mac - New platform in 2.0.0

  • Tizen - New platform in 2.0.0

  • Windows Phone 8.X - Retired. If you want to use it, it is there in 1.2.2

License

MIT License with the following override: The source code can not be used to create another NuGet package for public distribution. (Private distribution within your organization is OK.)

securestorage's People

Contributors

sameerkapps avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

securestorage's Issues

iOS storage key

This is related to the storage location issue, but slightly different.

I've used this plugin for a Xamarin app, then used that app code to start a different app. I changed the iOS bundle identifier (e.g. - com.edhubbell.app1 to com.edhubbell.app2) and the app name in the iOS section of Xamarin. However, once I start up the app, both apps refer to the older app's storage space.

I'm using the storage to store if a user is logged in. If I log in with app1 and then launch app2, app2 launches as if there is a user logged in. If I log out of app2 and then launch app1, app1 launches as if there is no user logged in. Both apps appear in the iOS simulator as app1 and app2, so iOS recognizes on some level that they are different apps. Separate launch icons, etc.

I realize this may be a Xamarin specific question, but if you've got an idea as to what I should change between the 2 apps so that iOS thinks these are 2 different apps from a storage standpoint, please let me know. I'm thinking there must be a product key or some other such thing that needs to change.

Excellent plugin, BTW. Works great for me. Thanks for any assistance you can provide.

~Ed

SecureStorageImplementation

Hi,

I have an application that has an android project, an iOS project, and a portable class library. I was wondering if there was a way I can store the code to provide session management inside of my portable class library. I'm also not sure where to set the
SecureStorageImplementation.StorageType = StorageTypes.PasswordProtectedFile
for sdk versions lesser than 26. I'm currently trying to implement this logic inside of my portable class library as a service that can be tested. The idea is to use the code in the portable class library for both iOS and android. I haven't been able to find any relatable examples in the samples you provided in the repo. This is my class implementation.

public class SessionService :  ISessionService
   {
       /// <summary>
       /// Method to retrieve an access token stored by <see cref="StoreSessionToken(SessionRequest)"/>
       /// </summary>
       /// <returns><see cref="SessionResponse"/></returns>
       public SessionResponse RetrieveSessionToken()
       {
           var accessToken = CrossSecureStorage.Current.GetValue("AccessToken");

           if (!string.IsNullOrWhiteSpace(accessToken))
           {
               return new SessionResponse() { Data = accessToken };
           }

           return new SessionResponse() { ErrorMessage = "Could not retrieve access token" };
       }

       /// <summary>
       /// Stores an access token used to maintain a logged in users permissions.
       /// </summary>
       /// <param name="request"><see cref="SessionRequest"/></param>
       /// <returns>bool in order indicate success.</returns>
       public bool StoreSessionToken(SessionRequest request)
       {
           CrossSecureStorage.Current.SetValue("AccessToken", request.Data);

           return CrossSecureStorage.Current.HasKey("AccessToken");
       }

       /// <summary>
       /// Clears out the token used to store a session.
       /// </summary>
       /// <returns>bool in order to indicate success.</returns>
       public bool ClearSessionToken()
       {
           CrossSecureStorage.Current.DeleteKey("AccessToken");

           return CrossSecureStorage.Current.HasKey("AccessToken");
       }

       public void SetBackwardsCompatibleSettings()
       {

           //Plugin.SecureStorage.SecureStorageImplementation secureStorage = new Plugin.SecureStorage.SecureStorageImplementation();
               
               //secureStorage .StorageType = Plugin.SecureStorage.StorageTypes.PasswordProtectedFile;
       }

Can't retrieve values on Android Simulator

Getting an UnrecoverableKeyException when trying to retrieve values from CrossSecureStorage on Xamarin Android. Issue doesn't happen on iOS.

I've seen it happen on android API level 25 and 27.
A reinstall of the app is usually needed to fix the issue.

Here's a stacktrace:

{Java.Security.UnrecoverableKeyException: Failed to obtain information about key ---> Java.Lang.Exception: -32
   --- End of inner exception stack trace ---
  at Java.Interop.JniEnvironment+InstanceMethods.CallNonvirtualObjectMethod (Java.Interop.JniObjectReference instance, Java.Interop.JniObjectReference type, Java.Interop.JniMethodInfo method, Java.Interop.JniArgumentValue* args) [0x00089] in <3beddfcb1eb547cd8ce47c3097f6eaeb>:0 
  at Java.Interop.JniPeerMembers+JniInstanceMethods.InvokeNonvirtualObjectMethod (System.String encodedMember, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters) [0x0001f] in <3beddfcb1eb547cd8ce47c3097f6eaeb>:0 
  at Java.Security.KeyStore.GetKey (System.String alias, System.Char[] password) [0x00043] in <ff9f3f3d4e134974a889db1b532c9b6e>:0 
  at Plugin.SecureStorage.AndroidKeyStoreImplementation+AndroidKeyStore.GetSymmetricKey () [0x00000] in <32517fff446a4abfbff8b506c1031d3c>:0 
  at Plugin.SecureStorage.AndroidKeyStoreImplementation+AndroidKeyStore.GetKey () [0x0000a] in <32517fff446a4abfbff8b506c1031d3c>:0 
  at Plugin.SecureStorage.AndroidKeyStoreImplementation+AndroidKeyStore.Decrypt (System.Byte[] data) [0x00009] in <32517fff446a4abfbff8b506c1031d3c>:0 
  at Plugin.SecureStorage.AndroidKeyStoreImplementation.GetValue (System.String key, System.String defaultValue) [0x0004e] in <32517fff446a4abfbff8b506c1031d3c>:0 
  at Plugin.SecureStorage.SecureStorageImplementation.GetValue (System.String key, System.String defaultValue) [0x00009] in <32517fff446a4abfbff8b506c1031d3c>:0 
  at App.Helpers.CartManager.get_CurrentCart () [0x00002] in /Path/to/File.cs:44 
  --- End of managed Java.Security.UnrecoverableKeyException stack trace ---
java.security.UnrecoverableKeyException: Failed to obtain information about key
	at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStoreSecretKeyFromKeystore(AndroidKeyStoreProvider.java:282)
	at android.security.keystore.AndroidKeyStoreSpi.engineGetKey(AndroidKeyStoreSpi.java:98)
	at java.security.KeyStore.getKey(KeyStore.java:1062)
	at md59d55c6560de094c7795e9ae0086e7c33.HomeActivity.n_onCreate(Native Method)
	at md59d55c6560de094c7795e9ae0086e7c33.HomeActivity.onCreate(HomeActivity.java:32)
	at android.app.Activity.performCreate(Activity.java:7009)
	at android.app.Activity.performCreate(Activity.java:7000)
	at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214)
	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731)
	at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856)
	at android.app.ActivityThread.-wrap11(Unknown Source:0)
	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)
	at android.os.Handler.dispatchMessage(Handler.java:106)
	at android.os.Looper.loop(Looper.java:164)
	at android.app.ActivityThread.main(ActivityThread.java:6494)
	at java.lang.reflect.Method.invoke(Native Method)
	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
Caused by: android.security.KeyStoreException: -32
	at android.security.KeyStore.getKeyStoreException(KeyStore.java:697)
	at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStoreSecretKeyFromKeystore(AndroidKeyStoreProvider.java:283)
	... 17 more
}

Key not saved/retrived on iOS 10 on simulator

Using your sample, I first this up on iOS 10 simulator, and the keys are not saved/retrieved.

I debugged through the code, and no exceptions are being thrown. Using the nugget package in my work app, saving always returns false.

steps:
enter values for key and value
press set key
press get value

expected: value to be retrieved
actual: no value is shown.

IOS KeyChain not saving value, xcode 9

Hi, I've been using the SecureStorage plugin on Android and UWP and it has been working fine. I just started testing IOS but the plugin/keychain only returns empty values. xcode 9, iphone 8 simulator. Custom Entitlements is not set. (Setting this causes a profiling error I cannot resolve at this time.)

I found this and wondered if it's related. https://forums.developer.apple.com/thread/87449. I am accessing the plugin for a portable library which seems different situation than their unit test issues.

Following is a clip of the code. SetValue does return false.
value = "test";
var r = CrossSecureStorage.Current.SetValue(key, value);
var v = CrossSecureStorage.Current.GetValue(key);
if ( v != value )
throw new Exception("R: " + r + ", Value: " + (v ?? "(null)") + ", orig: " + (value ?? "(null)"));

Output: R: False, Value: (null), orig: test

Hopefully, it's a mistake I am making; if so, I apologize for taking your time.

Thanks

Android Password

Just for my knowledge, why we need to define a password for Android devices? Is this one thing that can be generated automatically to be more secure?

Use the Android Keystore provider

Currently the Android keystore implementation is essentially not secure as there is no secure way to manage keys inside the app. Using the hardware serial number as the key provides no protection against knowledgeable attackers who root the phone. They are able to use the serial number themselves to decrypt the secrets file and get full access to stored secrets. Embedding the key in the app binary and using a key obfuscation system like Dotfuscator makes key retrieval a little harder, but a knowledgeable and persistent attacker is still able to reverse-engineer the obfuscation.

Since API level 18, Android provides the Android Keystore provider. Using the Android Keystore provider lets an individual app store its own credentials that only the app itself can access. This provides a way for apps to manage credentials that are usable only by itself while providing the same security benefits that the KeyChain API provides for system-wide credentials. This method requires no user interaction to select the credentials and assures that key material never enters the application process. When an application performs cryptographic operations using an Android Keystore key, behind the scenes plaintext, ciphertext, and messages to be signed or verified are fed to a system process which carries out the cryptographic operations.

You don't need to provide a password since the OS will derive it from your lock screen PIN and other variables itself and the secrets remain secure even if the adversary has rooted the phone.

Error trying to set StoragePassword for Xamarin Forms UWP NETStandard 2.0

Hi, we are successfully using SecureStorage on Xamarin Forms Android and iOS, and we recently started working on a Xamarin Forms UWP app. We have all of our Shared Code in the new templates using NETStandard 2.0, and when we try to set the StoragePassword in our UWP's App.xaml.cs file in the OnLaunched method, there isn't a StoragePassword property available to set. The SecureStorageImplementation is there, but no properties show up. We verified our references and NuGet packages are restored and resolved for this package and Xamarin Forms...the app runs fine when we comment out the StoragePassword code.

xamarin uwp securestorage

System.TypeLoadException: Could not resolve type with token

I'm new to the lib and didn't spend much time trying to use it. I installed it from NuGet into my PCL, my Droid and my iOS projects, then added this line to the MainActivity.cs and ran the app.

protected override void OnCreate(Bundle bundle)
{
   base.OnCreate(bundle);
   ...
   global::Xamarin.Forms.Forms.Init(this, bundle);
   SecureStorageImplementation.StoragePassword = "Your Password";
   ...
   LoadApplication(new App());
}

It crashes immediately with:

09-14 14:05:16.574 E/mono    (10534): 
09-14 14:05:16.574 E/mono    (10534): Unhandled Exception:
09-14 14:05:16.574 E/mono    (10534): System.TypeLoadException: Could not resolve type with token 0100003c (from typeref, class/assembly Plugin.SecureStorage.SecureStorageImplementation, Plugin.SecureStorage, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null)
09-14 14:05:16.579 E/mono-rt (10534): [ERROR] FATAL UNHANDLED EXCEPTION: System.TypeLoadException: Could not resolve type with token 0100003c (from typeref, class/assembly Plugin.SecureStorage.SecureStorageImplementation, Plugin.SecureStorage, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null)

Project with PlayServices fails

When using with Xamarin.GooglePlayServices.SafetyNet.60.1142.1 on Android 4 (including 4.4.3) the following method fails: CrossSecureStorage.Current.GetValue("SessionToken");

it was previously set with CrossSecureStorage.Current.SetValue("SessionToken", "passphrase");

It works fine until I add the following line to the start of the OnCreate method of my main activity:
Android.Gms.Security.ProviderInstaller.InstallIfNeeded(this);

Without that it works fine, but then older version of android are stuck without TLS1.1+ support and a whole load of other improvements.

Stack Trace:
Java.Security.InvalidKeyException: Unsupported key size: 24 bytes (must be 16 or 32)
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in :0
at Java.Interop.JniEnvironment+InstanceMethods.CallNonvirtualVoidMethod (Java.Interop.JniObjectReference instance, Java.Interop.JniObjectReference type, Java.Interop.JniMethodInfo method, Java.Interop.JniArgumentValue* args) [0x00089] in <7802aa64ad574c33adca332a3fa9706a>:0
at Java.Interop.JniPeerMembers+JniInstanceMethods.InvokeNonvirtualVoidMethod (System.String encodedMember, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters) [0x0001f] in <7802aa64ad574c33adca332a3fa9706a>:0
at Javax.Crypto.Cipher.Init (Javax.Crypto.CipherMode opmode, Java.Security.IKey key, Java.Security.Spec.IAlgorithmParameterSpec params) [0x00073] in <263adecfa58f4c449f1ff56156d886fd>:0
at Plugin.SecureStorage.AndroidKeyStoreImplementation+AndroidKeyStore.Decrypt (System.Byte[] data) [0x0003c] in <32517fff446a4abfbff8b506c1031d3c>:0
at Plugin.SecureStorage.AndroidKeyStoreImplementation.GetValue (System.String key, System.String defaultValue) [0x0004e] in <32517fff446a4abfbff8b506c1031d3c>:0
at Plugin.SecureStorage.SecureStorageImplementation.GetValue (System.String key, System.String defaultValue) [0x00009] in <32517fff446a4abfbff8b506c1031d3c>:0
at MyWayDigitalHealth.MyDiabetesMyWay.Data.SQLiteFactory.Connection (System.Boolean upgrade) [0x00051] in C:\Code\MDMW\MDMW.DataLayer\SQLiteFactory.cs:100
at MyWayDigitalHealth.MyDiabetesMyWay.Data.SQLiteFactory..ctor (MyWayDigitalHealth.MyDiabetesMyWay.Common.IAppSpecific appSpecific, System.Boolean encrypt, System.Boolean tryUpgrade) [0x00017] in C:\Code\MDMW\MDMW.DataLayer\SQLiteFactory.cs:79
at MyWayDigitalHealth.MyDiabetesMyWay.App+<>c__DisplayClass8_0+<<-ctor>b__0>d.MoveNext () [0x0005e] in C:\Code\MDMW\MDMW\App.xaml.cs:41
--- End of managed Java.Security.InvalidKeyException stack trace ---
java.security.InvalidKeyException: Unsupported key size: 24 bytes (must be 16 or 32)
at com.google.android.gms.org.conscrypt.OpenSSLCipher$EVP_AEAD$AES.checkSupportedKeySize(:com.google.android.gms@[email protected] (000308-197041431):3)
at com.google.android.gms.org.conscrypt.OpenSSLCipher.checkAndSetEncodedKey(:com.google.android.gms@[email protected] (000308-197041431):5)
at com.google.android.gms.org.conscrypt.OpenSSLCipher.engineInit(:com.google.android.gms@[email protected] (000308-197041431):7)
at javax.crypto.Cipher.init(Cipher.java:616)
at javax.crypto.Cipher.init(Cipher.java:566)
at dalvik.system.NativeStart.run(Native Method)

Data keeps stored after uninstalling the app

Hi there, nice plugin you have here, congratulations!
I used it to store sensitive data in my app. Now, it's in production and I have 2 iOS users which uninstalled the app and installed it again, so that they could erase the data stored at Secure Storage. Unfortunately, they reported that the previous data was not deleted and couldn't make it go away.

My question is, am I missing something or the data should be erased along with the app uninstall? If not, how can I achieve this?

EDIT: As of the readme.md

"iOS - The KeyChain access level is now set at AfterFirstUnlock as default. This will let app set the values in the background mode. As a result, the keys stored using the earlier versions will not be accessible with this version. To maintain backward compatibility, add a line to AppDelegate as follows:"

Sorry for my bad english reading, I couldn't undestand if the word version of the text is referring to the plugin's version or my app version.

Thanks for the attention :)

iOS 10 - values not persisting

After upgrading to iOS 10 (Xcode 8, iOS 10 simulators)
values saved with CrossSecureStorage.Current.SetValue([key],[value]) are not persisting

System.TypeLoadException: Could not resolve type with token 01000019

I'm getting this Exception from Output in an Android project build in Xamarin.Forms Solution from VS 2015:

Loaded assembly: MonoDroidConstructors [External]
09-27 17:42:53.970 D/Mono (28112): Assembly Ref addref AppConsume.Droid[0xb8cb1e90] -> mscorlib[0xb8c64d60]: 23
09-27 17:42:53.970 D/Mono (28112): Assembly Ref addref Xamarin.Forms.Core[0xb8cbf110] -> System.Collections[0xb8cc84e0]: 3
09-27 17:42:53.990 D/Mono (28112): Assembly Ref addref Xamarin.Forms.Core[0xb8cbf110] -> System.Threading[0xb8cd6378]: 3
09-27 17:42:54.030 D/Mono (28112): Assembly Ref addref AppConsume.Droid[0xb8cb1e90] -> Plugin.SecureStorage[0xb8cb6638]: 2
Unhandled Exception:

System.TypeLoadException: Could not resolve type with token 01000019

This is at Startup, my app builds correctly.

Can't Add to Project

Hi,
I have Xamarin Forms project using .net Standard 1.4 target.

I can add SecureStorage via Nuget but the Xamarin Forms project throws intellisense and compile time errors complaining it can't find/see SecureStorage. For example, either of the following lines don't work:

using SecureStorage;

SecureStorage.Current.HasKey("ApplicationId") ? "Y" : "N";

With responses like:
Severity Code Description Project File Line Suppression State Error CS0246 The type or namespace name 'SecureStorage' could not be found (are you missing a using directive or an assembly reference?) Wordbahn.FormsApp C:\Wordbahn\Wordbahn.FormsApp\App.xaml.cs 26 Active

I already had the Microsoft.NETCore.Portable.Compatibility project added and other PCL nugets work correctly.

I then tried download and building the repo and added the different assemblies to the respective Xamarin Forms and target platform projects. Same problem. The xamarin forms app doesn't see the SecureStorage types.

Any ideas?

Thanks,
Dave Gerding

AEADbadtagexception

Hi, I'm getting the above exception when I try to get a previous stored value. I'm using the package within a Xamarin.Forms Android app only. The issue appears to happen whenever the app has been re-opened after being closed. Can you please advise?

storage location

Where is this data stored? I deleted a test iOS app running on a simulator but the data stored with this plugin persisted.
Can you also please describe it's encryption technique.

Can't get plugin to run on iOS

I followed the suggestions to set "Enable Keychain" in Entitlements.plist file, and to set "Custom Entitlements" to that .plist file.
The project won't build. I get this error:
No valid iOP code signing kes found in keychain. You need to request a codesigning certificate from https://developer.apple.com

I have the same problem when trying to run the sample code. I'm running Visual Studio for mac.
Any suggestions?

Sharing violation on path Util.SecureStorage

Hi. In some devices like Galaxy Tab A 8.0,Galaxy J7,Galaxy J7 Neo, we got this error.

SecureStorageImplementation.Save ()
System.IO.IOException: Sharing violation on path Util.SecureStorage
Sharing violation on path Util.SecureStorage
System.IO.FileStream..ctor (System.String path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share, System.Int32 bufferSize, System.Boolean anonymous, System.IO.FileOptions options) [0x001b7] in <7822cfcead4342bf9d07f8ea73b8b0f8>:0
System.IO.FileStream..ctor (System.String path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share, System.Int32 bufferSize, System.Boolean isAsync, System.Boolean anonymous) [0x00000] in <7822cfcead4342bf9d07f8ea73b8b0f8>:0
System.IO.IsolatedStorage.IsolatedStorageFileStream..ctor (System.String path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share, System.Int32 bufferSize, System.IO.IsolatedStorage.IsolatedStorageFile isf) [0x0000a] in <7822cfcead4342bf9d07f8ea73b8b0f8>:0
System.IO.IsolatedStorage.IsolatedStorageFileStream..ctor (System.String path, System.IO.FileMode mode, System.IO.FileAccess access) [0x00000] in <7822cfcead4342bf9d07f8ea73b8b0f8>:0
(wrapper remoting-invoke-with-check) System.IO.IsolatedStorage.IsolatedStorageFileStream:.ctor (string,System.IO.FileMode,System.IO.FileAccess)
SecureStorageImplementation.Save ()
SecureStorageImplementation.SetValue (System.String key, System.String value)
RestService+d__10.MoveNext ()
ExceptionDispatchInfo.Throw ()
TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task)
TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task)
TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task)
TaskAwaiter1[TResult].GetResult () RestService+<PostAsync>d__4.MoveNext () ExceptionDispatchInfo.Throw () TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) TaskAwaiter1[TResult].GetResult ()
GpsService+d__4.MoveNext ()
ExceptionDispatchInfo.Throw ()
TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task)
TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task)
TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task)
TaskAwaiter`1[TResult].GetResult ()
AppWorker+d__6.MoveNext ()
ExceptionDispatchInfo.Throw ()
AsyncMethodBuilderCore+<>c.b__6_0 (System.Object state)
SyncContext+<>c__DisplayClass2_0.b__0 ()
Thread+RunnableImplementor.Run ()
IRunnableInvoker.n_Run (System.IntPtr jnienv, System.IntPtr native__this)
(wrapper dynamic-method) System.Object:d15f67f7-51c1-48f3-8679-f75ffacb48dc (intptr,intptr)

Does not work on Mac iOS Simulator, VS2019

Running on VS2019 16.1.3 and building on Mac machine with Mojave 10.14.5

Downloaded the sample app, and unloaded all projects except the iOS project. Built the project with the iOS project as startup, iOS Simulator for iPhone 8 iOS 12.2, keep getting the error message 'Could not find any available provisioning profiles for iOS.'

In the project properties, iOS Bundle Signing, Custom Entitlements - Entitlements.plist is chosen

In the Entitlements.plist, enable keychain is checked with the keychain group com.sameer.SecureStorageSample.

image

Please advise.

GetValue as SecureString

Unless I'm missing something, there's no way to recover the stored String as a .Net SecureString.

I'm not sure whether this is intended (because there's no way to recover the value from the OS without creating a String in memory with the value) or an omission that should be included...

System.NotImplementedException

Hello,

I'm just getting started with Xamarin, I'm making a PCL for both platforms and though iOS works perfectly, the same code on Android throws this error. I have the package added to both platforms. Am I missing something?

String deviceId = CrossSecureStorage.Current.GetValue("LHPEDeviceID", null); if(deviceId == null){ deviceId = Guid.NewGuid().ToString(); CrossSecureStorage.Current.SetValue("LHPEDeviceID", deviceId); }

Android FormatException when accessing a non existing value

When calling this code:
Convert.ToBoolean(CrossSecureStorage.Current.GetValue(nameof(MyProperty), false.ToString()))

I got this exception:

[0:] AndroidEnvironment.UnhandledExceptionRaiser: System.FormatException: Invalid length for a Base-64 char array or string.
  at System.Convert.FromBase64_Decode (System.Char* startInputPtr, System.Int32 inputLength, System.Byte* startDestPtr, System.Int32 destLength) [0x001db] in <d4a23bbd2f544c30a48c44dd622ce09f>:0 
  at System.Convert.FromBase64CharPtr (System.Char* inputPtr, System.Int32 inputLength) [0x00031] in <d4a23bbd2f544c30a48c44dd622ce09f>:0 
  at System.Convert.FromBase64String (System.String s) [0x00025] in <d4a23bbd2f544c30a48c44dd622ce09f>:0 
  at Plugin.SecureStorage.AndroidKeyStoreImplementation.GetValue (System.String key, System.String defaultValue) [0x00036] in <32517fff446a4abfbff8b506c1031d3c>:0 
  at Plugin.SecureStorage.SecureStorageImplementation.GetValue (System.String key, System.String defaultValue) [0x00009] in <32517fff446a4abfbff8b506c1031d3c>:0 

Is there a way to prevent the exception on Android? It don't come up on iOS and I don't like the way to use try-catch all over the place in my getters.

Not fully compatible with .NETStandard

warning NU1701: Package 'sameerIOTApps.Plugin.SecureStorage 2.0.0' was restored using '.NETFramework,Version=v4.6.1' instead of the project target framework '.NETStandard,Version=v2.0'. This package may not be fully compatible with your project.

System.NotImplementedException

After installed via NuGet, I try to run a project in Windows 8 or Android, and I get this:

System.NotImplementedException: This functionality is not implemented in the portable version of this assembly. You should reference the NuGet package from your main application project in order to reference the platform-specific implementation.

It does mean that is not available in PCL projects, only in shared?

Android release build crashes while trying to decrypt data from the Android KeyStore

I'm using version 1.3.1, targeting Android 10.0 (Q) (API 29). The issue occurred on my OnePlus 5T (Android 9 security patch 1 December 2019).

The stack trace (app identifiers replaced with *****):

2020-02-07 19:00:35.112 24401-24401/? E/AndroidRuntime: FATAL EXCEPTION: main
    Process: *****, PID: 24401
    android.runtime.JavaProxyThrowable: MvvmCross.Exceptions.MvxException: Problem navigating to ViewModel InterstitialViewModel ---> MvvmCross.Exceptions.MvxException: Failed to construct and initialize ViewModel for type *****.Core.ViewModels.InterstitialViewModel from locator MvxDefaultViewModelLocator - check InnerException for more information ---> MvvmCross.Exceptions.MvxException: Problem creating viewModel of type InterstitialViewModel ---> MvvmCross.Exceptions.MvxIoCResolveException: Failed to construct TetherDeviceService ---> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> Java.Security.GeneralSecurityException: Exception of type 'Java.Security.GeneralSecurityException' was thrown. ---> Java.Lang.Exception: Signature/MAC verification failed
       --- End of inner exception stack trace ---
      at Java.Interop.JniEnvironment+InstanceMethods.CallNonvirtualObjectMethod (Java.Interop.JniObjectReference instance, Java.Interop.JniObjectReference type, Java.Interop.JniMethodInfo method, Java.Interop.JniArgumentValue* args) <0x704fe222d0 + 0x000b7> in <c7ee2790529640cdbb5b7aa7889014aa>:0 
      at Java.Interop.JniPeerMembers+JniInstanceMethods.InvokeNonvirtualObjectMethod (System.String encodedMember, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters) <0x704fe25b80 + 0x000b3> in <c7ee2790529640cdbb5b7aa7889014aa>:0 
      at Javax.Crypto.Cipher.DoFinal (System.Byte[] input, System.Int32 inputOffset, System.Int32 inputLen) [0x00052] in <4993a3b290714f409bbb9e88a3193954>:0 
      at Plugin.SecureStorage.AndroidKeyStoreImplementation+AndroidKeyStore.Decrypt (System.Byte[] data) [0x0005f] in <744f44ee05674e8bafdb613951f6815b>:0 
      at Plugin.SecureStorage.AndroidKeyStoreImplementation.GetValue (System.String key, System.String defaultValue) [0x0004e] in <744f44ee05674e8bafdb613951f6815b>:0 
      at Plugin.SecureStorage.SecureStorageImplementation.GetValue (System.String key, System.String defaultValue) [0x00009] in <744f44ee05674e8bafdb613951f6815b>:0 
      at *****.Core.Services.SecureStorageService.GetValue (System.String key) [0x00005] in <dae77869776043c6bd1aebc1ccf425f7>:0 
      at *****.Core.Services.TetherDeviceService..ctor (*****.Core.Services.ISecureStorageService secureStorageService, *****.Core.Services.Abstractions.IHttpService httpService, *****.Core.Services.IRemoteConfigurationService remoteConfigurationService) [0x00031] in <dae77869776043c6bd1aebc1ccf425f7>:0 
        at (wrapper managed-to-native) System.Reflection.RuntimeConstructorInfo.InternalInvoke(System.Reflection.RuntimeConstructorInfo,object,object[],System.Exception&)
      at System.Reflection.RuntimeConstructorInfo.InternalInvoke (System.Object obj, System.Object[] parameters, System.Boolean wrapExceptions) <0x70502428a0 + 0x00037> in <e172acb0ee254f27a4fa374cc5316622>:0 
       --- End of inner exception stack trace ---
      at System.Reflection.RuntimeConstructorInfo.InternalInvoke (System.Object obj, System.Object[] parameters, System.Boolean wrapExceptions) <0x70502428a0 + 0x00080> in <e172acb0ee254f27a4fa374cc5316622>:0 
      at System.Reflection.RuntimeConstructorInfo.DoInvoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) <0x70502426d0 + 0x00177> in <e172acb0ee254f27a4fa374cc5316622>:0 
      at System.Reflection.RuntimeConstructorInfo.Invoke (System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) <0x7050242970 + 0x00037> in <e172acb0ee254f27a4fa374cc5316622>:0 
      at System.Reflection.ConstructorInfo.Invoke (System.Object[] parameters) <0x7050240ab0 + 0x00033> in <e172acb0ee254f27a4fa374cc5316622>:0 

My app immediately crashes after trying to retrieve a value from secure storage. For what it's worth, I've only observed this issue within a release build and when the value being retrieved doesn't exist yet. The offending line seems to be:

CrossSecureStorage.Current.GetValue(key);

where key is just a constant string. The app is trying to read securely stored credentials at startup to communicate with an API, but is crashing in trying to read the value on first load, possibly because the value doesn't exist yet.

I have found that setting android:allowBackup="false" in my manifest seems to be a viable workaround for this issue (in my case). I suspect that using CrossSecureStorage.Current.HasKey(key); before GetValue(key) would also solve the issue, but I haven't tried that yet.

Umlaut Problem in Android

Hello,
I have problems with German Umlaut's when restoring strings with the SecureStorage Plugin. The strings are saved as e.g. "Zürich" and then when I retrieve the string back with .GetValue I get "Z?rich" back. This problem only occurs on Android.

Support backup accessibility keys for Keychain items

As is, if a manual backup is made, without a password, an attacker can access the encrypted Keychain Items, and with some degree of effort, decrypt them.

Adding support for the kSecAttrAccessible key would allow to better restrict when a "keychain item is accessible."

Values you use with the kSecAttrAccessible attribute key.

  • let kSecAttrAccessibleAfterFirstUnlock: CFString
    • The data in the keychain item cannot be accessed after a restart until the device has been unlocked once by the user.
  • let kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly: CFString
    • The data in the keychain item cannot be accessed after a restart until the device has been unlocked once by the user.
  • let kSecAttrAccessibleAlways: CFString
    • The data in the keychain item can always be accessed regardless of whether the device is locked.
      let kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly: CFString
    • The data in the keychain can only be accessed when the device is unlocked. Only available if a passcode is set on the device.
  • let kSecAttrAccessibleAlwaysThisDeviceOnly: CFString
    • The data in the keychain item can always be accessed regardless of whether the device is locked.
  • let kSecAttrAccessibleWhenUnlocked: CFString
    • The data in the keychain item can be accessed only while the device is unlocked by the user.
  • let kSecAttrAccessibleWhenUnlockedThisDeviceOnly: CFString
    • The data in the keychain item can be accessed only while the device is unlocked by the user.

Source: Item Attribute Keys and Values

Is it possible to add support for this?

Thank you.

System.ArgumentException: Handle must be valid. Parameter name: instance on CrossSecureStorage

Lately the xamarin android app is crashing randomly on CrossSecureStorage with error as below:

public static string CrossSecureUserTypeKey { get; } = "UserType"; //Located in Statics.cs var UserType = Plugin.SecureStorage.CrossSecureStorage.Current.GetValue(Statics.CrossSecureUserTypeKey);

Error:

System.ArgumentException: Handle must be valid. Parameter name: type at Java.Interop.JniEnvironment+InstanceMethods.GetMethodID (Java.Interop.JniObjectReference type, System.String name, System.String signature) [0x00009] in :0 at Android.Runtime.JNIEnv.GetMethodID (System.IntPtr kls, System.String name, System.String signature) [0x00007] in :0 at Android.Content.ISharedPreferencesInvoker.Contains (System.String key) [0x00012] in :0 at Plugin.SecureStorage.SecureStorage.HasKey (System.String key) [0x0000d] in :0 at drappme.MainActivity.b__40_0 () [0x00018]

any thoughts?

FileNotFoundException

When accessing CrossSecureStorage.Current from android app, and FileNotFoundException is thrown
(seems to be handled internally)
Could not find file "Util.SecureStorage"

  • this expected behavior?

iOS Not Able to Return Vale

Hi,
I have the entitlements property set to:

<dict>
	<key>keychain-access-groups</key>
	<array>
		<string>fadsdasdad96.com.wordbahn.app.ios</string>
	</array>
</dict>

Which is a real iOS cert/provision etc... The project builds and runs. But I'm not getting correct values back when I try and persist a user Id on startup using the following code:

bool hasCachedAppId = false;
            try
            {
                hasCachedAppId= CrossSecureStorage.Current.HasKey("OwnerId");
            }
            catch (Exception ex)
            {
                var ErrMessage = ex.Message;
            }

            if (!hasCachedAppId)
            {
                if (!CrossConnectivity.Current.IsConnected)
                {
                    throw new NotImplementedException("Add offline page popup here");
                }
                else
                {
                    //call backend GetOwnerIdWithDeviceDetails
                    try
                    {
                        var tempGuid = Guid.NewGuid().ToString();
                        CrossSecureStorage.Current.SetValue("OwnerId", tempGuid);
                        var checkGuid = CrossSecureStorage.Current.GetValue("OwnerId");

                        if (tempGuid==checkGuid)
                        {
                            IsUsingDeviceUserId = true;
                            UserId = tempGuid;
                        }
                        else
                        {
                            throw new Exception("Failed to access read or write device secure storage.");
                        }
                    }
                    catch (Exception e)
                    {
                        TrackException("Secure Storage read or write failed during app init.", e, true);
                    }
                }
            }
            else
            {
                try
                {
                    UserId = CrossSecureStorage.Current.GetValue("OwnerId");
                    IsUsingDeviceUserId = true;
                }
                catch (Exception e)
                {
                    TrackException("Secure Storage read or write failed during app init.", e, true);

                }
            }

Are there any additional steps needed beyond the entitlements property to get iOS secure storage to work? The code works in Android.

Thanks!
Dave G

Exception thrown: Java.Lang.NoSuchMethodError

Hi!

I'm getting the following error in my Xamarin Forms application:
[ERROR] FATAL UNHANDLED EXCEPTION: System.TypeInitializationException: The type initializer for 'Plugin.SecureStorage.SecureStorageImplementation' threw an exception. ---> Java.Lang.NoSuchMethodError: no static method "Landroid/os/Build;.getSerial()Ljava/lang/String;"

This is thrown when I try to use the SetValue method:
CrossSecureStorage.Current.SetValue("test", "123");

I'm using SecureStorage version 2.0.1 (although, I'm also getting the problem in version 2.0).

Any clues?
Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.