// Path: rxfingerprint/src/main/java/com/mtramin/rxfingerprint/data/FingerprintEncryptionResult.java
// public class FingerprintEncryptionResult extends FingerprintAuthenticationResult {
// 
//     private final String encrypted;
// 
//     /**
//      * Default constructor
//      *
//      * @param result    result of the operation
//      * @param message   message to be displayed to the user
//      * @param encrypted encrypted data
//      */
//     public FingerprintEncryptionResult(FingerprintResult result, String message, String encrypted) {
//         super(result, message);
//         this.encrypted = encrypted;
//     }
// 
//     /**
//      * @return encrypted data, can only be accessed if the result was of
//      * type {@link FingerprintResult#AUTHENTICATED}
//      */
//     public String getEncrypted() {
//         if (!isSuccess()) {
//             throw new IllegalAccessError("Fingerprint authentication was not successful, cannot access encryption result");
//         }
//         return encrypted;
//     }
// }
// 
// Path: rxfingerprint/src/main/java/com/mtramin/rxfingerprint/data/FingerprintResult.java
// public enum FingerprintResult {
//     FAILED, HELP, AUTHENTICATED
// }


import javax.crypto.spec.IvParameterSpec;
import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import android.annotation.SuppressLint;
import android.content.Context;
import android.hardware.fingerprint.FingerprintManager.AuthenticationResult;
import android.hardware.fingerprint.FingerprintManager.CryptoObject;
import android.support.annotation.Nullable;
import com.mtramin.rxfingerprint.data.FingerprintEncryptionResult;
import com.mtramin.rxfingerprint.data.FingerprintResult;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.util.Arrays;
import javax.crypto.Cipher;
							AesCipherProvider cipherProvider,
							char[] toEncrypt,
							EncodingProvider encodingProvider) {
		super(fingerprintApiWrapper);
		this.cipherProvider = cipherProvider;

		if (toEncrypt == null) {
			throw new NullPointerException("String to be encrypted is null. Can only encrypt valid strings");
		}
		this.toEncrypt = toEncrypt;
		this.encodingProvider = encodingProvider;
	}

	@Nullable
	@Override
	protected CryptoObject initCryptoObject(ObservableEmitter<FingerprintEncryptionResult> emitter) {
		try {
			Cipher cipher = cipherProvider.getCipherForEncryption();
			return new CryptoObject(cipher);
		} catch (Exception e) {
			emitter.onError(e);
			return null;
		}
	}

	@Override
	protected void onAuthenticationSucceeded(ObservableEmitter<FingerprintEncryptionResult> emitter, AuthenticationResult result) {
		try {
			Cipher cipher = result.getCryptoObject().getCipher();
			byte[] encryptedBytes = cipher.doFinal(ConversionUtils.toBytes(toEncrypt));
// Path: rxfingerprint/src/main/java/com/mtramin/rxfingerprint/data/FingerprintEncryptionResult.java
// public class FingerprintEncryptionResult extends FingerprintAuthenticationResult {
// 
//     private final String encrypted;
// 
//     /**
//      * Default constructor
//      *
//      * @param result    result of the operation
//      * @param message   message to be displayed to the user
//      * @param encrypted encrypted data
//      */
//     public FingerprintEncryptionResult(FingerprintResult result, String message, String encrypted) {
//         super(result, message);
//         this.encrypted = encrypted;
//     }
// 
//     /**
//      * @return encrypted data, can only be accessed if the result was of
//      * type {@link FingerprintResult#AUTHENTICATED}
//      */
//     public String getEncrypted() {
//         if (!isSuccess()) {
//             throw new IllegalAccessError("Fingerprint authentication was not successful, cannot access encryption result");
//         }
//         return encrypted;
//     }
// }
// 
// Path: rxfingerprint/src/main/java/com/mtramin/rxfingerprint/data/FingerprintResult.java
// public enum FingerprintResult {
//     FAILED, HELP, AUTHENTICATED
// }


// Path: rxfingerprint/src/main/java/com/mtramin/rxfingerprint/AesEncryptionObservable.java
import javax.crypto.spec.IvParameterSpec;
import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import android.annotation.SuppressLint;
import android.content.Context;
import android.hardware.fingerprint.FingerprintManager.AuthenticationResult;
import android.hardware.fingerprint.FingerprintManager.CryptoObject;
import android.support.annotation.Nullable;
import com.mtramin.rxfingerprint.data.FingerprintEncryptionResult;
import com.mtramin.rxfingerprint.data.FingerprintResult;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.util.Arrays;
import javax.crypto.Cipher;

							AesCipherProvider cipherProvider,
							char[] toEncrypt,
							EncodingProvider encodingProvider) {
		super(fingerprintApiWrapper);
		this.cipherProvider = cipherProvider;

		if (toEncrypt == null) {
			throw new NullPointerException("String to be encrypted is null. Can only encrypt valid strings");
		}
		this.toEncrypt = toEncrypt;
		this.encodingProvider = encodingProvider;
	}

	@Nullable
	@Override
	protected CryptoObject initCryptoObject(ObservableEmitter<FingerprintEncryptionResult> emitter) {
		try {
			Cipher cipher = cipherProvider.getCipherForEncryption();
			return new CryptoObject(cipher);
		} catch (Exception e) {
			emitter.onError(e);
			return null;
		}
	}

	@Override
	protected void onAuthenticationSucceeded(ObservableEmitter<FingerprintEncryptionResult> emitter, AuthenticationResult result) {
		try {
			Cipher cipher = result.getCryptoObject().getCipher();
			byte[] encryptedBytes = cipher.doFinal(ConversionUtils.toBytes(toEncrypt));
			byte[] ivBytes = cipher.getParameters().getParameterSpec(IvParameterSpec.class).getIV();