Integração de Biometria com Android usando DigitalPersona U.are.U
Autor: Rafael | Publicado: 2016-07-23T00:50:00-03:00


Introdução

U.are.U for Android SDK é um kit de desenvolvimento da DigitalPersona, atual Crossmatch, para autenticação de impressão digital.

Você vai precisar fazer três processos:

1- Registro da Digital (Enrollment)
2- Captura da Digital (Capture)
3- Comparação do Registro com a Captura (Compare)








O Registro consiste em coletar um certo número de imagens da impressão digital, pra que você crie um conjunto de minúcias chamado FMD, ou Fingerprint Minutiae Data, que serão armazenados em algum formato no seu banco de dados, por exemplo o ISO_19794_2_2005. Esse formato padroniza os dados das minúcias, assim você pode utilizar com outras SDK's ou integrar com outros sistemas.

A Captura coleta uma imagem e assim podemos criar um FMD de Captura para comparação com o FMD de Registro.

A comparação faz um match, ou casamento do FMD de Registro com o FMD de Captura e retorna um score de similaridade entre as duas digitais.


O que é necessário ?

1- Faça o download da SDK no site da Crossmatch.

2- Você vai precisar de um leitor de impressão digital da Crossmatch.

Utilizei o EikonTouch 510, pois na época, o U.are.U 5160 precisava de um rooted Android, inviabilizando certos clientes. Outros detalhes são que os Eikon Touch são mais leves e por serem capacitivos, consomem menos energia para tablets e celulares.

3- Android 5.x


Registro (Enrollment)

Para efetuar o registro da digital usando a SDK, você vai criar um callback para extrair e retornar cada FMD:

int resolution = 500;
Engine engine = UareUGlobal.GetEngine();
Fmd fmd = engine.CreateEnrollmentFmd(fmdFormat, new EnrollmentCallback() {

&nbsp;&nbsp;&nbsp; @Override
&nbsp;&nbsp;&nbsp; public PreEnrollmentFmd GetFmd(Format format) {

&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; try {
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Fmd fmd = capture(reader,
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Fid.Format.ISO_19794_4_2005, Fmd.Format.ISO_19794_2_2005, resolution);
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(fmd != null) {

&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Engine.PreEnrollmentFmd prefmd = null;

&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; prefmd = new Engine.PreEnrollmentFmd();
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; prefmd.fmd = fmd;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; prefmd.view_index = 0;

&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return prefmd;

&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } else {
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return null;

&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }

&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } catch(Exception e) {
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; throw new RuntimeException("Erro ao extrair caracteristicas.", e);
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp; }

});
A maioria das vezes, você vai precisar coletar 4 digitais para compor um FMD de registro.&nbsp;&nbsp;&nbsp; 

Captura (Capture)

Para efetuar uma captura:


private Fmd capture(
&nbsp;&nbsp; &nbsp;Reader reader, 
&nbsp;&nbsp; &nbsp;Fid.Format fidFormat, Fmd.Format fmdFormat, int resolution) throws UareUException {
&nbsp;&nbsp; 
&nbsp;&nbsp; &nbsp;Fmd fmd = null;
&nbsp;&nbsp; &nbsp;while(fmd == null) {
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;Reader.CaptureResult result = 
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;reader.Capture(fidFormat, Reader.ImageProcessing.IMG_PROC_DEFAULT, resolution, -1);
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;// verificando a qualidade
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if(result.image != null &amp;&amp; 
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;result.quality == Reader.CaptureQuality.GOOD) {
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;Engine engine = UareUGlobal.GetEngine();
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;fmd = engine.CreateFmd(result.image, fmdFormat);
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp; &nbsp;}
&nbsp;&nbsp; 
&nbsp;&nbsp; &nbsp;return fmd;
}

Utilize resolution de 500dpi. Atualmente é o padrão de qualidade para impressões digitais.



Comparação (Compare)

Depois de ter o FMD de registro e o FMD de captura, você pode agora fazer a comparação das duas digitais:

Engine engine = UareUGlobal.GetEngine();
int score = engine.Compare(enrolledFmd, 0, capturedFmd, 0);&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; 
Um score com um valor menor de 100, já é um valor aceitável, mas você pode diminuir esse valor caso queira uma maior precisão.

Android

A SDK se comporta da mesma forma, tanto no Android quanto no Desktop, as diferenças são que você precisa solicitar permissão de acesso a USB e usar o context do Android para listar os leitores conectados na USB.

Solicitar a permissão para uso da USB utilizando um BroadcastReceiver:

private static final String ACTION_USB_PERMISSION = "com.digitalpersona.uareu.dpfpddusbhost.USB_PERMISSION";

private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
&nbsp;&nbsp; &nbsp;public void onReceive(Context context, Intent intent) {
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;String action = intent.getAction();
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if (ACTION_USB_PERMISSION.equals(action)) {
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;synchronized (this) {
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if(device != null){
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;// sua lógica
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}
&nbsp;&nbsp; &nbsp;}
};


private boolean requestPermission(Reader reader) throws DPFPDDUsbException {
&nbsp;&nbsp; &nbsp;if(reader.GetDescription().technology == Reader.Technology.HW_TECHNOLOGY_CAPACITIVE) {
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;PendingIntent mPermissionIntent;
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;mPermissionIntent = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), 0);
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;context.registerReceiver(mUsbReceiver, filter);

&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if(DPFPDDUsbHost.DPFPDDUsbCheckAndRequestPermissions(context, mPermissionIntent, reader.GetDescription().name))
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;return true;
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;} else {
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;return false;
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}
&nbsp;&nbsp; &nbsp;}

&nbsp;&nbsp; &nbsp;return true;
}
&nbsp;&nbsp;&nbsp; 
Listando os leitores conectados:

ReaderCollection readers = UareUGlobal.GetReaderCollection(context);
readers.GetReaders();

for(Reader i : readers) {
&nbsp;&nbsp;&nbsp; System.out.println(i.GetDescription().serial_number);
}


Questões de Segurança

- Tente utilizar algum tipo de criptografia mais um token ou timestamp de verificação da digital lida. Isso garante que ela seja usada somente um vez.
- A SDK dá a possibilidade de você comparar a digital dentro do Android, mas veja se isso não pode se tornar uma falha de segurança da sua aplicação, já que a comparação será feita dentro do device do cliente.

Exemplos













Referências

DigitalPersona OneTouch

Solução

Procurando uma solução completa e fácil de integrar. Veja os exemplos da Naskar BioCloud.