implemented test for fingerprint auth
This commit is contained in:
		| @@ -9,8 +9,11 @@ using Android.Hardware.Fingerprints; | |||||||
| using Android.OS; | using Android.OS; | ||||||
| using Android.Security.Keystore; | using Android.Security.Keystore; | ||||||
| using Android.Preferences; | using Android.Preferences; | ||||||
|  | using Android.Util; | ||||||
|  | using Android.Widget; | ||||||
| using Java.IO; | using Java.IO; | ||||||
| using Java.Security.Cert; | using Java.Security.Cert; | ||||||
|  | using Javax.Crypto.Spec; | ||||||
|  |  | ||||||
| namespace keepass2android | namespace keepass2android | ||||||
| { | { | ||||||
| @@ -25,7 +28,7 @@ namespace keepass2android | |||||||
|  |  | ||||||
| 		public FingerprintManager FingerprintManager  | 		public FingerprintManager FingerprintManager  | ||||||
| 		{ | 		{ | ||||||
| 			get { return (FingerprintManager) Context.GetSystemService("FingerprintManager"); } | 			get { return (FingerprintManager) Context.GetSystemService(Context.FingerprintService); } | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		public KeyguardManager KeyguardManager  | 		public KeyguardManager KeyguardManager  | ||||||
| @@ -103,8 +106,9 @@ namespace keepass2android | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	public class FingerprintEncryptionModule: FingerprintManager.AuthenticationCallback | 	public abstract class FingerprintCrypt: FingerprintManager.AuthenticationCallback | ||||||
| 	{ | 	{ | ||||||
|  | 		protected const string FailedToInitCipher = "Failed to init Cipher"; | ||||||
| 		public override void OnAuthenticationError(FingerprintState errorCode, ICharSequence errString) | 		public override void OnAuthenticationError(FingerprintState errorCode, ICharSequence errString) | ||||||
| 		{ | 		{ | ||||||
| 			_callback.OnAuthenticationError(errorCode, errString); | 			_callback.OnAuthenticationError(errorCode, errString); | ||||||
| @@ -126,37 +130,191 @@ namespace keepass2android | |||||||
| 			_callback.OnAuthenticationSucceeded(result); | 			_callback.OnAuthenticationSucceeded(result); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		private readonly FingerprintModule _fingerprint; | 		protected readonly string _keyId; | ||||||
| 		private readonly string _keyId; |  | ||||||
| 		private Cipher _cipher; | 		protected Cipher _cipher; | ||||||
| 		private bool _selfCancelled; | 		private bool _selfCancelled; | ||||||
| 		private CancellationSignal _cancellationSignal; | 		private CancellationSignal _cancellationSignal; | ||||||
| 		private FingerprintManager.CryptoObject _cryptoObject; | 		protected FingerprintManager.CryptoObject _cryptoObject; | ||||||
| 		private FingerprintManager.AuthenticationCallback _callback; | 		private FingerprintManager.AuthenticationCallback _callback; | ||||||
|  | 		protected KeyStore _keystore; | ||||||
| 		 | 		 | ||||||
| 		public FingerprintEncryptionModule(FingerprintModule fingerprint, string keyId) | 		private FingerprintManager _fingerprintManager; | ||||||
|  |  | ||||||
|  | 		public FingerprintCrypt(FingerprintModule fingerprint, string keyId) | ||||||
| 		{ | 		{ | ||||||
| 			_fingerprint = fingerprint; | 			 | ||||||
| 			_keyId = keyId; | 			_keyId = keyId; | ||||||
|  | 			 | ||||||
| 			_cipher = fingerprint.Cipher; | 			_cipher = fingerprint.Cipher; | ||||||
|  | 			_keystore = fingerprint.Keystore; | ||||||
|  | 			 | ||||||
|  | 			_fingerprintManager = fingerprint.FingerprintManager; | ||||||
|  | 			 | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		public abstract bool InitCipher(); | ||||||
|  | 		protected static string GetAlias(string keyId) | ||||||
|  | 		{ | ||||||
|  | 			return "keepass2android." + keyId; | ||||||
|  | 		} | ||||||
|  | 		protected static string GetIvPrefKey(string prefKey) | ||||||
|  | 		{ | ||||||
|  | 			return prefKey + "_iv"; | ||||||
|  | 		} | ||||||
|  | 		public bool IsFingerprintAuthAvailable | ||||||
|  | 		{ | ||||||
|  | 			get | ||||||
|  | 			{ | ||||||
|  | 				return _fingerprintManager.IsHardwareDetected | ||||||
|  | 					&& _fingerprintManager.HasEnrolledFingerprints; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		public void StartListening(FingerprintManager.AuthenticationCallback callback) | ||||||
|  | 		{ | ||||||
|  | 			if (!IsFingerprintAuthAvailable) | ||||||
|  | 				return; | ||||||
|  |  | ||||||
|  | 			_cancellationSignal = new CancellationSignal(); | ||||||
|  | 			_selfCancelled = false; | ||||||
|  | 			_callback = callback; | ||||||
|  | 			_fingerprintManager.Authenticate(_cryptoObject, _cancellationSignal, 0 /* flags */, this, null); | ||||||
|  | 			 | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		public void StopListening() | ||||||
|  | 		{ | ||||||
|  | 			if (_cancellationSignal != null) | ||||||
|  | 			{ | ||||||
|  | 				_selfCancelled = true; | ||||||
|  | 				_cancellationSignal.Cancel(); | ||||||
|  | 				_cancellationSignal = null; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		public string Encrypt(string textToEncrypt) | ||||||
|  | 		{ | ||||||
|  | 			return Base64.EncodeToString(_cipher.DoFinal(System.Text.Encoding.UTF8.GetBytes(textToEncrypt)), 0); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 		public void StoreEncrypted(string textToEncrypt, string prefKey, Context context) | ||||||
|  | 		{ | ||||||
|  | 			var edit = PreferenceManager.GetDefaultSharedPreferences(context).Edit(); | ||||||
|  |  | ||||||
|  | 			edit.PutString(prefKey, Encrypt(textToEncrypt)); | ||||||
|  | 			edit.PutString(GetIvPrefKey(prefKey), Base64.EncodeToString(CipherIv,0)); | ||||||
|  | 			edit.Commit(); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		 | ||||||
|  |  | ||||||
|  | 		private byte[] CipherIv | ||||||
|  | 		{ | ||||||
|  | 			get { return _cipher.GetIV(); } | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	public class FingerprintDecryption : FingerprintCrypt | ||||||
|  | 	{ | ||||||
|  | 		private readonly byte[] _iv; | ||||||
|  | 		 | ||||||
|  |  | ||||||
|  | 		public FingerprintDecryption(FingerprintModule fingerprint, string keyId, byte[] iv) : base(fingerprint, keyId) | ||||||
|  | 		{ | ||||||
|  | 			_iv = iv; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		public FingerprintDecryption(FingerprintModule fingerprint, string keyId, Context context, string prefKey) | ||||||
|  | 			: base(fingerprint, keyId) | ||||||
|  | 		{ | ||||||
|  | 			_iv = Base64.Decode(PreferenceManager.GetDefaultSharedPreferences(context).GetString(GetIvPrefKey(prefKey), null), 0); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		public override bool InitCipher() | ||||||
|  | 		{ | ||||||
|  | 			 | ||||||
|  | 			try | ||||||
|  | 			{ | ||||||
|  | 				_keystore.Load(null); | ||||||
|  | 				var key = _keystore.GetKey(GetAlias(_keyId), null); | ||||||
|  | 				var ivParams = new IvParameterSpec(_iv); | ||||||
|  | 				_cipher.Init(CipherMode.DecryptMode, key, ivParams); | ||||||
|  |  | ||||||
|  | 				_cryptoObject = new FingerprintManager.CryptoObject(_cipher); | ||||||
|  | 				return true; | ||||||
|  | 			} | ||||||
|  | 			catch (KeyPermanentlyInvalidatedException) | ||||||
|  | 			{ | ||||||
|  | 				return false; | ||||||
|  | 			} | ||||||
|  | 			catch (KeyStoreException e) | ||||||
|  | 			{ | ||||||
|  | 				throw new RuntimeException(FailedToInitCipher, e); | ||||||
|  | 			} | ||||||
|  | 			catch (CertificateException e) | ||||||
|  | 			{ | ||||||
|  | 				throw new RuntimeException(FailedToInitCipher, e); | ||||||
|  | 			} | ||||||
|  | 			catch (UnrecoverableKeyException e) | ||||||
|  | 			{ | ||||||
|  | 				throw new RuntimeException(FailedToInitCipher, e); | ||||||
|  | 			} | ||||||
|  | 			catch (IOException e) | ||||||
|  | 			{ | ||||||
|  | 				throw new RuntimeException(FailedToInitCipher, e); | ||||||
|  | 			} | ||||||
|  | 			catch (NoSuchAlgorithmException e) | ||||||
|  | 			{ | ||||||
|  | 				throw new RuntimeException(FailedToInitCipher, e); | ||||||
|  | 			} | ||||||
|  | 			catch (InvalidKeyException e) | ||||||
|  | 			{ | ||||||
|  | 				throw new RuntimeException(FailedToInitCipher, e); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 		public string Decrypt(string encryted) | ||||||
|  | 		{ | ||||||
|  | 			byte[] encryptedBytes = Base64.Decode(encryted, 0); | ||||||
|  | 			return System.Text.Encoding.UTF8.GetString(_cipher.DoFinal(encryptedBytes)); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		public string DecryptStored(string prefKey, Context context) | ||||||
|  | 		{ | ||||||
|  | 			string enc = PreferenceManager.GetDefaultSharedPreferences(context).GetString(prefKey, null); | ||||||
|  |  | ||||||
|  | 			Toast.MakeText(context, "len="+Base64.Decode(enc, 0).Length.ToString(), ToastLength.Long).Show(); | ||||||
|  | 			return Decrypt(enc); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	public class FingerprintEncryption : FingerprintCrypt | ||||||
|  | 	{ | ||||||
|  | 		 | ||||||
|  | 		private KeyGenerator _keyGen; | ||||||
|  | 		 | ||||||
|  |  | ||||||
|  | 		public FingerprintEncryption(FingerprintModule fingerprint, string keyId) :  | ||||||
|  | 			base(fingerprint, keyId) | ||||||
|  | 		{ | ||||||
|  | 			_keyGen = fingerprint.KeyGenerator; | ||||||
| 			CreateKey(); | 			CreateKey(); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  |  | ||||||
| 		/// <summary> | 		/// <summary> | ||||||
| 		/// Creates a symmetric key in the Android Key Store which can only be used after the user  | 		/// Creates a symmetric key in the Android Key Store which can only be used after the user  | ||||||
| 		/// has authenticated with fingerprint. | 		/// has authenticated with fingerprint. | ||||||
| 		/// </summary> | 		/// </summary> | ||||||
| 		private void CreateKey() | 		private void CreateKey() | ||||||
| 		{ | 		{ | ||||||
| 			// The enrolling flow for fingerprint. This is where you ask the user to set up fingerprint |  | ||||||
| 			// for your flow. Use of keys is necessary if you need to know if the set of |  | ||||||
| 			// enrolled fingerprints has changed. |  | ||||||
| 			try | 			try | ||||||
| 			{ | 			{ | ||||||
| 				_fingerprint.Keystore.Load(null); | 				_keystore.Load(null); | ||||||
| 				// Set the alias of the entry in Android KeyStore where the key will appear | 				_keyGen.Init(new KeyGenParameterSpec.Builder(GetAlias(_keyId), | ||||||
| 				// and the constrains (purposes) in the constructor of the Builder |  | ||||||
| 				_fingerprint.KeyGenerator.Init(new KeyGenParameterSpec.Builder(GetAlias(_keyId), |  | ||||||
| 					KeyStorePurpose.Encrypt | KeyStorePurpose.Decrypt) | 					KeyStorePurpose.Encrypt | KeyStorePurpose.Decrypt) | ||||||
| 					.SetBlockModes(KeyProperties.BlockModeCbc) | 					.SetBlockModes(KeyProperties.BlockModeCbc) | ||||||
| 					// Require the user to authenticate with a fingerprint to authorize every use | 					// Require the user to authenticate with a fingerprint to authorize every use | ||||||
| @@ -164,7 +322,7 @@ namespace keepass2android | |||||||
| 					.SetUserAuthenticationRequired(true) | 					.SetUserAuthenticationRequired(true) | ||||||
| 					.SetEncryptionPaddings(KeyProperties.EncryptionPaddingPkcs7) | 					.SetEncryptionPaddings(KeyProperties.EncryptionPaddingPkcs7) | ||||||
| 					.Build()); | 					.Build()); | ||||||
| 				_fingerprint.KeyGenerator.GenerateKey(); | 				_keyGen.GenerateKey(); | ||||||
| 			} | 			} | ||||||
| 			catch (NoSuchAlgorithmException e) | 			catch (NoSuchAlgorithmException e) | ||||||
| 			{ | 			{ | ||||||
| @@ -184,13 +342,14 @@ namespace keepass2android | |||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		public bool InitCipher() | 		public override bool InitCipher() | ||||||
| 		{ | 		{ | ||||||
| 			try | 			try | ||||||
| 			{ | 			{ | ||||||
| 				_fingerprint.Keystore.Load(null); | 				_keystore.Load(null); | ||||||
| 				var key = _fingerprint.Keystore.GetKey(GetAlias(_keyId), null); | 				var key = _keystore.GetKey(GetAlias(_keyId), null); | ||||||
| 				_cipher.Init(CipherMode.EncryptMode, key); | 				_cipher.Init(CipherMode.EncryptMode, key); | ||||||
|  |  | ||||||
| 				_cryptoObject = new FingerprintManager.CryptoObject(_cipher); | 				_cryptoObject = new FingerprintManager.CryptoObject(_cipher); | ||||||
| 				return true; | 				return true; | ||||||
| 			} | 			} | ||||||
| @@ -200,69 +359,28 @@ namespace keepass2android | |||||||
| 			} | 			} | ||||||
| 			catch (KeyStoreException e) | 			catch (KeyStoreException e) | ||||||
| 			{ | 			{ | ||||||
| 				throw new RuntimeException("Failed to init Cipher", e); | 				throw new RuntimeException(FailedToInitCipher, e); | ||||||
| 			} | 			} | ||||||
| 			catch (CertificateException e) | 			catch (CertificateException e) | ||||||
| 			{ | 			{ | ||||||
| 				throw new RuntimeException("Failed to init Cipher", e); | 				throw new RuntimeException(FailedToInitCipher, e); | ||||||
| 			} | 			} | ||||||
| 			catch (UnrecoverableKeyException e) | 			catch (UnrecoverableKeyException e) | ||||||
| 			{ | 			{ | ||||||
| 				throw new RuntimeException("Failed to init Cipher", e); | 				throw new RuntimeException(FailedToInitCipher, e); | ||||||
| 			} | 			} | ||||||
| 			catch (IOException e) | 			catch (IOException e) | ||||||
| 			{ | 			{ | ||||||
| 				throw new RuntimeException("Failed to init Cipher", e); | 				throw new RuntimeException(FailedToInitCipher, e); | ||||||
| 			} | 			} | ||||||
| 			catch (NoSuchAlgorithmException e) | 			catch (NoSuchAlgorithmException e) | ||||||
| 			{ | 			{ | ||||||
| 				throw new RuntimeException("Failed to init Cipher", e); | 				throw new RuntimeException(FailedToInitCipher, e); | ||||||
| 			} | 			} | ||||||
| 			catch (InvalidKeyException e) | 			catch (InvalidKeyException e) | ||||||
| 			{ | 			{ | ||||||
| 				throw new RuntimeException("Failed to init Cipher", e); | 				throw new RuntimeException(FailedToInitCipher, e); | ||||||
| 			} | 			} | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		private string GetAlias(string keyId) |  | ||||||
| 		{ |  | ||||||
| 			return "keepass2android." + keyId; |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		public bool IsFingerprintAuthAvailable |  | ||||||
| 		{ |  | ||||||
| 			get |  | ||||||
| 			{ |  | ||||||
| 				return _fingerprint.FingerprintManager.IsHardwareDetected |  | ||||||
| 					&& _fingerprint.FingerprintManager.HasEnrolledFingerprints; |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		public void StartListening(FingerprintManager.AuthenticationCallback callback) |  | ||||||
| 		{ |  | ||||||
| 			if (!IsFingerprintAuthAvailable) |  | ||||||
| 				return; |  | ||||||
|  |  | ||||||
| 			_cancellationSignal = new CancellationSignal(); |  | ||||||
| 			_selfCancelled = false; |  | ||||||
| 			_callback = callback; |  | ||||||
| 			_fingerprint.FingerprintManager.Authenticate(_cryptoObject, _cancellationSignal, 0 /* flags */, this, null); |  | ||||||
| 			 |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		public void StopListening() |  | ||||||
| 		{ |  | ||||||
| 			if (_cancellationSignal != null) |  | ||||||
| 			{ |  | ||||||
| 				_selfCancelled = true; |  | ||||||
| 				_cancellationSignal.Cancel(); |  | ||||||
| 				_cancellationSignal = null; |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		public void Encrypt(string textToEncrypt) |  | ||||||
| 		{ |  | ||||||
| 			_cipher.DoFinal(MemUtil) |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @@ -81,7 +81,7 @@ | |||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <XamarinComponentReference Include="xamandroidsupportv7appcompat"> |     <XamarinComponentReference Include="xamandroidsupportv7appcompat"> | ||||||
|       <Visible>False</Visible> |       <Visible>False</Visible> | ||||||
|       <Version>21.0.3.0</Version> |       <Version>22.2.0.0</Version> | ||||||
|     </XamarinComponentReference> |     </XamarinComponentReference> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" /> |   <Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" /> | ||||||
|   | |||||||
| @@ -47,14 +47,22 @@ | |||||||
|     <Reference Include="System.Core" /> |     <Reference Include="System.Core" /> | ||||||
|     <Reference Include="System.Xml.Linq" /> |     <Reference Include="System.Xml.Linq" /> | ||||||
|     <Reference Include="System.Xml" /> |     <Reference Include="System.Xml" /> | ||||||
|  |     <Reference Include="Xamarin.Android.Support.v4"> | ||||||
|  |       <HintPath>..\packages\Xamarin.Android.Support.v4.23.1.1.0\lib\MonoAndroid403\Xamarin.Android.Support.v4.dll</HintPath> | ||||||
|  |     </Reference> | ||||||
|  |     <Reference Include="Xamarin.Android.Support.v7.AppCompat"> | ||||||
|  |       <HintPath>..\packages\Xamarin.Android.Support.v7.AppCompat.23.1.1.0\lib\MonoAndroid403\Xamarin.Android.Support.v7.AppCompat.dll</HintPath> | ||||||
|  |     </Reference> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|  |     <Compile Include="FingerprintModule.cs" /> | ||||||
|     <Compile Include="MainActivity.cs" /> |     <Compile Include="MainActivity.cs" /> | ||||||
|     <Compile Include="Resources\Resource.Designer.cs" /> |     <Compile Include="Resources\Resource.Designer.cs" /> | ||||||
|     <Compile Include="Properties\AssemblyInfo.cs" /> |     <Compile Include="Properties\AssemblyInfo.cs" /> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <None Include="GettingStarted.Xamarin" /> |     <None Include="GettingStarted.Xamarin" /> | ||||||
|  |     <None Include="packages.config" /> | ||||||
|     <None Include="Resources\AboutResources.txt" /> |     <None Include="Resources\AboutResources.txt" /> | ||||||
|     <None Include="Assets\AboutAssets.txt" /> |     <None Include="Assets\AboutAssets.txt" /> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
| @@ -70,6 +78,12 @@ | |||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <None Include="Properties\AndroidManifest.xml" /> |     <None Include="Properties\AndroidManifest.xml" /> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|  |   <ItemGroup> | ||||||
|  |     <XamarinComponentReference Include="xamandroidsupportv7appcompat"> | ||||||
|  |       <Visible>False</Visible> | ||||||
|  |       <Version>21.0.3.0</Version> | ||||||
|  |     </XamarinComponentReference> | ||||||
|  |   </ItemGroup> | ||||||
|   <Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" /> |   <Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" /> | ||||||
|   <!-- To modify your build process, add your task inside one of the targets below and uncomment it.  |   <!-- To modify your build process, add your task inside one of the targets below and uncomment it.  | ||||||
|      Other similar extension points exist, see Microsoft.Common.targets. |      Other similar extension points exist, see Microsoft.Common.targets. | ||||||
|   | |||||||
| @@ -14,10 +14,11 @@ using keepass2android; | |||||||
|  |  | ||||||
| namespace FingerprintTest | namespace FingerprintTest | ||||||
| { | { | ||||||
| 	[Activity(Label = "FingerprintTest", MainLauncher = true, Icon = "@drawable/icon")] | 	[Activity(Label = "FingerprintTest", MainLauncher = true, Icon = "@drawable/icon", Theme = "@style/Theme.AppCompat")] | ||||||
| 	public class MainActivity : AppCompatActivity | 	public class MainActivity : AppCompatActivity | ||||||
| 	{ | 	{ | ||||||
| 		int count = 1; | 		int count = 1; | ||||||
|  | 		private string _keyId = "mykeyid"; | ||||||
| 		const int FINGERPRINT_PERMISSION_REQUEST_CODE = 0; | 		const int FINGERPRINT_PERMISSION_REQUEST_CODE = 0; | ||||||
|  |  | ||||||
| 		protected override void OnCreate(Bundle bundle) | 		protected override void OnCreate(Bundle bundle) | ||||||
| @@ -32,26 +33,61 @@ namespace FingerprintTest | |||||||
| 			Button button = FindViewById<Button>(Resource.Id.MyButton); | 			Button button = FindViewById<Button>(Resource.Id.MyButton); | ||||||
| 			button.Visibility = ViewStates.Gone; | 			button.Visibility = ViewStates.Gone; | ||||||
| 			 | 			 | ||||||
|  |  | ||||||
| 			RequestPermissions(new[] { Manifest.Permission.UseFingerprint }, FINGERPRINT_PERMISSION_REQUEST_CODE); | 			RequestPermissions(new[] { Manifest.Permission.UseFingerprint }, FINGERPRINT_PERMISSION_REQUEST_CODE); | ||||||
| 		} | 		} | ||||||
|  | 		string prefKey = "enc_pref_key"; | ||||||
|  |  | ||||||
| 		public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults) | 		public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults) | ||||||
| 		{ | 		{ | ||||||
| 			if (requestCode == FINGERPRINT_PERMISSION_REQUEST_CODE && grantResults[0] == Android.Content.PM.Permission.Granted) | 			if (requestCode == FINGERPRINT_PERMISSION_REQUEST_CODE && grantResults[0] == Android.Content.PM.Permission.Granted) | ||||||
| 			{ | 			{ | ||||||
| 				Button button = FindViewById<Button>(Resource.Id.MyButton); | 				Button encButton = FindViewById<Button>(Resource.Id.MyButton); | ||||||
| 				button.Visibility = ViewStates.Visible; | 				Button decButton = FindViewById<Button>(Resource.Id.Decrypt); | ||||||
| 				button.Enabled = true; | 				encButton.Visibility = ViewStates.Visible; | ||||||
|  | 				encButton.Enabled = true; | ||||||
| 				var fingerprint = new keepass2android.FingerprintModule(this); | 				var fingerprint = new keepass2android.FingerprintModule(this); | ||||||
|  |  | ||||||
| 				button.Click += (sender, args) => | 				encButton.Click += (sender, args) => | ||||||
| 				{ | 				{ | ||||||
| 					 | 					 | ||||||
|  | 					var fingerprintEnc = new FingerprintEncryption(fingerprint, _keyId); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 					if (fingerprintEnc.InitCipher()) | ||||||
|  | 					{ | ||||||
|  | 						fingerprintEnc.StartListening(new EncryptionCallback(this, fingerprintEnc, prefKey)); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 					} | ||||||
|  | 					else | ||||||
|  | 					{ | ||||||
|  | 						Toast.MakeText(this, "Error initiating cipher", ToastLength.Long).Show(); | ||||||
|  | 					} | ||||||
|  |  | ||||||
| 				}; | 				}; | ||||||
|  |  | ||||||
|  | 				decButton.Click += (sender, args) => | ||||||
|  | 				{ | ||||||
|  | 					 | ||||||
|  | 					var fingerprintDec = new FingerprintDecryption(fingerprint, _keyId, this, prefKey); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 					if (fingerprintDec.InitCipher()) | ||||||
|  | 					{ | ||||||
|  | 						fingerprintDec.StartListening(new DecryptionCallback(this, fingerprintDec,prefKey)); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 					} | ||||||
|  | 					else | ||||||
|  | 					{ | ||||||
|  | 						Toast.MakeText(this, "Error initiating cipher", ToastLength.Long).Show(); | ||||||
|  | 					} | ||||||
|  |  | ||||||
|  | 				}; | ||||||
|  |  | ||||||
| 				if (!fingerprint.KeyguardManager.IsKeyguardSecure) | 				if (!fingerprint.KeyguardManager.IsKeyguardSecure) | ||||||
| 				{ | 				{ | ||||||
| 					button.Enabled = false; | 					encButton.Enabled = false; | ||||||
| 					// Show a message that the user hasn't set up a fingerprint or lock screen. | 					// Show a message that the user hasn't set up a fingerprint or lock screen. | ||||||
| 					Toast.MakeText(this, "Secure lock screen hasn't set up.\n" | 					Toast.MakeText(this, "Secure lock screen hasn't set up.\n" | ||||||
| 						+ "Go to 'Settings -> Security -> Fingerprint' to set up a fingerprint", ToastLength.Long).Show(); | 						+ "Go to 'Settings -> Security -> Fingerprint' to set up a fingerprint", ToastLength.Long).Show(); | ||||||
| @@ -61,45 +97,55 @@ namespace FingerprintTest | |||||||
|  |  | ||||||
| 				if (!fingerprint.FingerprintManager.HasEnrolledFingerprints) | 				if (!fingerprint.FingerprintManager.HasEnrolledFingerprints) | ||||||
| 				{ | 				{ | ||||||
| 					button.Enabled = false; | 					encButton.Enabled = false; | ||||||
| 					// This happens when no fingerprints are registered. | 					// This happens when no fingerprints are registered. | ||||||
| 					Toast.MakeText(this, "Go to 'Settings -> Security -> Fingerprint' " + | 					Toast.MakeText(this, "Go to 'Settings -> Security -> Fingerprint' " + | ||||||
| 						"and register at least one fingerprint", ToastLength.Long).Show(); | 						"and register at least one fingerprint", ToastLength.Long).Show(); | ||||||
| 					return; | 					return; | ||||||
| 				} | 				} | ||||||
| 				var fingerprintEnc = new FingerprintEncryptionModule(fingerprint, "abc"); |  | ||||||
| 				 | 				 | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 					if (fingerprintEnc.InitCipher()) | 	public class DecryptionCallback : FingerprintManager.AuthenticationCallback | ||||||
| 	{ | 	{ | ||||||
| 						fingerprintEnc.StartListening(new EncryptionCallback(this, fingerprintEnc)); | 		private readonly Context _context; | ||||||
|  | 		private readonly FingerprintDecryption _fingerprintDec; | ||||||
|  | 		private readonly string _prefKey; | ||||||
|  |  | ||||||
| 						 | 		public DecryptionCallback(Context context, FingerprintDecryption fingerprintDec, string prefKey) | ||||||
| 					} |  | ||||||
| 					else |  | ||||||
| 		{ | 		{ | ||||||
| 						Toast.MakeText(this, "Error initiating cipher", ToastLength.Long).Show(); | 			_context = context; | ||||||
|  | 			_fingerprintDec = fingerprintDec; | ||||||
|  | 			_prefKey = prefKey; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 			} | 		public override void OnAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) | ||||||
|  | 		{ | ||||||
|  | 			var prefs = PreferenceManager.GetDefaultSharedPreferences(Application.Context); | ||||||
|  | 			Toast.MakeText(_context, _fingerprintDec.DecryptStored(_prefKey, _context), ToastLength.Long).Show(); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	public class EncryptionCallback : FingerprintManager.AuthenticationCallback | 	public class EncryptionCallback : FingerprintManager.AuthenticationCallback | ||||||
| 	{ | 	{ | ||||||
| 		private readonly FingerprintEncryptionModule _fingerprintEnc; | 		private readonly FingerprintCrypt _fingerprintEnc; | ||||||
|  | 		private readonly string _prefKey; | ||||||
|  |  | ||||||
| 		public EncryptionCallback(Context context, FingerprintEncryptionModule fingerprintEnc) | 		public EncryptionCallback(Context context, FingerprintCrypt fingerprintEnc, string prefKey) | ||||||
| 		{ | 		{ | ||||||
| 			_fingerprintEnc = fingerprintEnc; | 			_fingerprintEnc = fingerprintEnc; | ||||||
|  | 			_prefKey = prefKey; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		public override void OnAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) | 		public override void OnAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) | ||||||
| 		{ | 		{ | ||||||
| 			_fingerprintEnc.Encrypt("abc"); | 			 | ||||||
| 			var edit = PreferenceManager.GetDefaultSharedPreferences(Application.Context).Edit(); | 			_fingerprintEnc.StoreEncrypted("some töst data", _prefKey, Application.Context); | ||||||
| 			edit.PutString("encrypted", ); |  | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | 		 | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,5 +1,6 @@ | |||||||
| <?xml version="1.0" encoding="utf-8"?> | <?xml version="1.0" encoding="utf-8"?> | ||||||
| <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="FingerprintTest.FingerprintTest" android:versionCode="1" android:versionName="1.0"> | <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="FingerprintTest.FingerprintTest" android:versionCode="1" android:versionName="1.0"> | ||||||
| 	<uses-sdk android:targetSdkVersion="15" /> | 	<uses-sdk android:targetSdkVersion="15" /> | ||||||
|  |   <uses-permission android:name="android.permission.USE_FINGERPRINT" /> | ||||||
| 	<application android:label="FingerprintTest" android:icon="@drawable/Icon"></application> | 	<application android:label="FingerprintTest" android:icon="@drawable/Icon"></application> | ||||||
| </manifest> | </manifest> | ||||||
| @@ -2,12 +2,15 @@ | |||||||
| <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||||||
|     android:orientation="vertical" |     android:orientation="vertical" | ||||||
|     android:layout_width="fill_parent" |     android:layout_width="fill_parent" | ||||||
|     android:layout_height="fill_parent" |     android:layout_height="fill_parent"> | ||||||
|     > |  | ||||||
|     <Button |     <Button | ||||||
|         android:id="@+id/MyButton" |         android:id="@+id/MyButton" | ||||||
|         android:layout_width="fill_parent" |         android:layout_width="fill_parent" | ||||||
|         android:layout_height="wrap_content" |         android:layout_height="wrap_content" | ||||||
|     android:text="@string/Hello" |         android:text="@string/Hello" /> | ||||||
|     /> |     <Button | ||||||
|  |         android:id="@+id/Decrypt" | ||||||
|  |         android:layout_width="fill_parent" | ||||||
|  |         android:layout_height="wrap_content" | ||||||
|  |         android:text="Decrypt" /> | ||||||
| </LinearLayout> | </LinearLayout> | ||||||
		Reference in New Issue
	
	Block a user
	 Philipp Crocoll
					Philipp Crocoll