Шифрование и дешифрование данных с помощью FingerPrint Auth в Xamarin. Android - PullRequest
0 голосов
/ 13 июля 2020

Я пытаюсь зашифровать и расшифровать сообщение spesifi c, используя аутентификацию по отпечатку пальца. Но я не мог понять, как это сделать. Например, когда я пытаюсь получить Cipher.DoFinal (), я получаю исключение Illegal Block Size Exception. Что мне не хватает? Вот моя реализация:

CryptoObjectHelper.cs

  public class CryptoObjectHelper
{
    // This can be key name you want. Should be unique for the app.
    static readonly string KEY_NAME = "com.xamarin.android.sample.fingerprint_authentication_key";
    // We always use this keystore on Android.
    static readonly string KEYSTORE_NAME = "AndroidKeyStore";
    // Should be no need to change these values.
    static readonly string KEY_ALGORITHM = KeyProperties.KeyAlgorithmAes;
    static readonly string BLOCK_MODE = KeyProperties.BlockModeCbc;
    static readonly string ENCRYPTION_PADDING = KeyProperties.EncryptionPaddingPkcs7;
    static readonly string TRANSFORMATION = KEY_ALGORITHM + "/" +
                                            BLOCK_MODE + "/" +
                                            ENCRYPTION_PADDING;
    readonly KeyStore _keystore;

    public CryptoObjectHelper()
    {
        _keystore = KeyStore.GetInstance(KEYSTORE_NAME);
        _keystore.Load(null);
    }
    public Cipher CreateCipher(bool retry = true)
    {
        IKey key = GetKey();
        Cipher cipher = Cipher.GetInstance(TRANSFORMATION);
        try
        {
            cipher.Init(CipherMode.EncryptMode, key);
        }
        catch (KeyPermanentlyInvalidatedException e)
        {
            _keystore.DeleteEntry(KEY_NAME);
            if (retry)
            {
                CreateCipher(false);
            }
            else
            {
                throw new Exception("Could not create the cipher for fingerprint authentication.", e);
            }
        }
        return cipher;
    }

    IKey GetKey()
    {
        IKey secretKey;
        if (!_keystore.IsKeyEntry(KEY_NAME))
        {
            CreateKey();
        }

        secretKey = _keystore.GetKey(KEY_NAME, null);
        return secretKey;
    }

    void CreateKey()
    {
        KeyGenerator keyGen = KeyGenerator.GetInstance(KeyProperties.KeyAlgorithmAes, KEYSTORE_NAME);
        KeyGenParameterSpec keyGenSpec =
            new KeyGenParameterSpec.Builder(KEY_NAME, KeyStorePurpose.Encrypt | KeyStorePurpose.Decrypt)
                .SetBlockModes(BLOCK_MODE)
                .SetEncryptionPaddings(ENCRYPTION_PADDING)
                .SetUserAuthenticationRequired(true)
                .Build();
        keyGen.Init(keyGenSpec);
        keyGen.GenerateKey();
    }
    public FingerprintManagerCompat.CryptoObject BuildCryptoObject()
    {
        Cipher cipher = CreateCipher();
        return new FingerprintManagerCompat.CryptoObject(cipher);
    }
}

FingerPrintHandler.cs

 internal class FingerprintHandler : FingerprintManager.AuthenticationCallback
{
    private Context mainActivity;
    public FingerprintHandler(Context mainActivity)
    {
        this.mainActivity = mainActivity;
    }
    internal void StartAuthentication(FingerprintManager fingerprintManager, FingerprintManager.CryptoObject cryptoObject)
    {
        CancellationSignal cancellationSignal = new CancellationSignal();
        if (ActivityCompat.CheckSelfPermission(mainActivity, Manifest.Permission.UseFingerprint)
            != (int)Android.Content.PM.Permission.Granted)
            return;
        fingerprintManager.Authenticate(cryptoObject, cancellationSignal, 0, this, null);
    }
    public override void OnAuthenticationFailed()
    {
        Toast.MakeText(mainActivity, "Fingerprint Authentication failed!", ToastLength.Long).Show();
    }
    public override void OnAuthenticationSucceeded(FingerprintManager.AuthenticationResult result)
    {
        Toast.MakeText(mainActivity, "Fingerprint Authentication Success!", ToastLength.Long).Show();
    }

}

MainActivity.cs

protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        Xamarin.Essentials.Platform.Init(this, savedInstanceState);
        SetContentView(Resource.Layout.activity_main);
        Android.Support.V7.Widget.Toolbar toolbar = FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
        SetSupportActionBar(toolbar);


        var cipher = helper.CreateCipher();
        FingerprintManager fingerprintManager = (FingerprintManager)GetSystemService(FingerprintService);
        FingerprintManager.CryptoObject cryptoObject = new FingerprintManager.CryptoObject(cipher);
        FingerprintHandler handler = new FingerprintHandler(this);
        handler.StartAuthentication(fingerprintManager, cryptoObject);
    }

Спасибо за любые помощь и совет

...