Autenticación biométrica de voz con Twilio

June 04, 2014
Redactado por

Autenticación biométrica de voz con Twilio

¿Qué pasaría si pudiera usar su voz como una contraseña, diciendo una frase que solo funcionará si es usted quien la dice?  Eso sería incluso más seguro que una contraseña compleja, porque la voz de una persona es más difícil de duplicar que cualquier contraseña.

Escena de la película Minority Report

Bueno, puede utilizar la autenticación biométrica de voz.  Las técnicas de autenticación biométrica de voz, mediante el uso de técnicas de muestreo digital para reconocer la voz de un orador, están ganando popularidad en numerosas industrias.   Las organizaciones que han implementado con normalidad la tecnología de autenticación de voz son grandes, como bancos y departamentos gubernamentales. Organizaciones que han aumentado sus preocupaciones por la seguridad tanto como los fondos para implementar una compleja tecnología de autenticación de voz.

Sin embargo, el campo está cambiando, y ahora se puede acceder a la autenticación de voz a través de las API, la forma en que Twilio ha puesto a disposición las comunicaciones a través de las API.

¿Qué es?

He querido establecer una prueba de concepto con autenticación biológica por voz desde la primera vez que escuché acerca de esta, pero me costó encontrar una API que fuera utilizable sin una sobrecarga grande.  Afortunadamente, Noel Grover, de VoiceIt se comunicó con nosotros y pude configurar una demostración de autenticación de voz basada en Twilio en un instante.

Un caso de uso común es la autenticación de dos factores.  Por ejemplo, durante una transferencia bancaria o el inicio de sesión en la aplicación, el flujo sería similar a la autenticación de dos factores de Twilio, pero en lugar de ingresar un código mediante SMS o IVR, se debe reconocer una voz.

Puedes intentarlo tú mismo llamando al +1 612-400-7423

Elementos básicos:

Primero, es necesario familiarizarse con algunos conceptos clave que me resultaron un complicados al principio, pero son bastante estándares en el campo.

1.  Inscripción: este es el proceso de creación de una impresión de voz. Por lo general, se le pedirá a un usuario que repita una frase varias veces y la grabación de estos enunciados se comparará con los futuros intentos de autenticación.

2. Autenticación: esta es la comparación de una frase de usuario con una inscripción registrada.  Estos algoritmos son sintonizables, acompañan y determinan cuán estricto o flexible debe ser el algoritmo de coincidencia.   Y VoiceIT tiene la capacidad de autenticarse a través de una API de REST y un archivo wav, que es particularmente conveniente con Twilio.

3. Usuarios: autoexplicativo; para usar VoiceIt, necesita crear un usuario.  Este usuario es un consejo para utilizar Twilio con VoiceIt. En lugar de hacer que un usuario cree un nombre de usuario, es probable que desee utilizar su número de teléfono y colocarlo en el formato de correo electrónico que requieran.

4. Estos conceptos y otros se tratan en la API de VoiceIt.

El código

En esta demostración, utilizaré un sistema que, cuando recibe una llamada, reconoce el número y, si el usuario existe, le permite iniciar sesión mediante su frase de contraseña.  Si su voz coincide con la frase pregrabada, la demostración simplemente dirá “thanks your voice has been recognized” (Gracias, tu voz ha sido reconocida).  Si no se reconocen las personas que llaman, pueden inscribirse como un usuario nuevo.

Para la API de VoiceIT basada en REST, se realizó la integración con Twilio de forma súper fácil.  Aquí hay un ejemplo en Node, que ha hecho muy fácil la solicitud de un servicio a otro.

Comenzaremos con algunos requisitos básicos de Node y utilizaremos Express para que podamos recibir solicitudes web de Twilio.

// # Twilio & VoiceIt Demo

// This application demonstrates how Twilio integrates with the VoiceIt
// Voiceprint Portal, allowing for biometric authentication with your voice
// applications.

// Standard Operating Procedure
// -------------------------------

var twilio     = require('twilio'),
    SHA256     = require('crypto-js/sha256'),
    bodyParser = require('body-parser'),
    express    = require('express'),
    request    = require('request');

// Prepare the Express server and body parsing middleware.
var port = process.env.PORT || 1337;
var app = express();
app.use(bodyParser());


 

Necesitarás una ID de desarrollador de VoiceIt; puedes registrarte directamente en su sitio web para establecerla.  En este código, el ID para desarrolladores se almacena en una variable de entorno llamada VOICEIT_DEV_ID.

var VOICEIT_DEV_ID = process.env.VOICEIT_DEV_ID;

A continuación, escribimos una función auxiliar , callerCredentials, que se utilizará más adelante, cada vez que recibamos una nueva llamada al sistema.

// Stubbing VoiceIt Profiles with Phone Numbers
// --------------------------------------------
// VoiceIt authentication requires an email address, so we will make a fake
// one for this caller using the response body posted from Twilio.
var callerCredentials = function(body) {
   // Twilio's `body.From` is the caller's phone number, so let's use it as
   // identifier in the VoiceIt profile. It also means, the authentication is
   // bound only to this phone number.
   return  {
     number   : body.From,
     email    : body.From + '@twiliobioauth.example.com',
     password : SHA256(body.From)
   };
};

A continuación, configuramos la sección del código que aceptará solicitudes de Twilio cuando se realice una llamada entrante.  Tenga en cuenta que el método es /incoming_call. Si su servidor se ejecuta en  http://yourtwilioserver.yourcompany.com/, debe configurar la URL de voz de su número de teléfono Twilio a = http://yourtwilioserver.yourcompany.com/incoming_call.

Esto enviará llamadas entrantes a esta sección del código.  A partir de entonces, ocurrirá lo siguiente:

1. El número de teléfono entrante de la persona que llama se utilizará para crear credenciales de usuario con la función calderCredentials. Hay que tener en cuenta que en esta demostración la única parte excepcional del registro del usuario es el número de teléfono desde el que llaman.

2. Se realiza una llamada a la API contra VoiceIt usándolas para obtener información sobre el usuario. Si no existe, crear el usuario en VoiceIt.

3. Si el usuario de VoiceIt no existe, iniciar el proceso para /enroll (inscribir) al usuario.

4. Reproducir algunos comentarios a la persona que llama mediante TwiML.

// Accept Incoming Calls
// ---------------------
// We need to accept incoming calls from Twilio. The fully-qualified URL should
// be added to your Twilio account and publicly available.
app.post('/incoming_call', function(req, res) {
  var caller  = callerCredentials(req.body);
  var twiml   = new twilio.TwimlResponse();
  // Prepare options for the VoiceIt `GET /sivservice/api/users` API request.
  var options = {
    url: 'https://siv.voiceprintportal.com/sivservice/api/users',
    headers: {
      'VsitEmail'       : caller.email,
      'VsitPassword'    : caller.password,
      'VsitDeveloperId' : VOICEIT_DEV_ID
    }
  };

  request(options, function (error, response,  body) {
    // When VoiceIt responds with at `200`, we know the user's account profile
    // exists in the VoiceIt system.
    if (!error && response.statusCode == 200) {
      var voiceIt = JSON.parse(body);

      // Greet the caller when their account profile is recognized by the VoiceIt API.
      twiml.say(
        'You have called Voice Authentication. Your phone number has been recognized.'
      );
      // Let's provide the caller with an opportunity to enroll by typing `1` on
      // their phone's keypad.
      twiml.gather({
        action    : '/enroll_or_authenticate',
        numDigits : 1,
        timeout   : 3
      }, function () {
        this.say(
          'You can now log in, or press 1 now to enroll for the first time.'
        );
      });
      twiml.redirect('/enroll_or_authenticate?digits=TIMEOUT');

      res.send(twiml.toString());
    } else {
      switch(response.statusCode) {
        // Create a VoiceIt user when the HTTP status is `412 Precondition Failed`.
        case 412:
          // Prepare options for the VoiceIt `POST /sivservice/api/users` API request.
          var options = {
            url: 'https://siv.voiceprintportal.com/sivservice/api/users',
            headers: {
              'VsitDeveloperId' : VOICEIT_DEV_ID,
              'VsitEmail'       : caller.email,
              'VsitFirstName'   : 'First' + caller.number,
              'VsitLastName'    : 'Last' + caller.number,
              'VsitPassword'    : caller.password,
              'VsitPhone1'      : caller.number
            }
          };

          request.post(options, function (error, response,  body) {
            if (!error && response.statusCode == 200) {
              var voiceIt = JSON.parse(body);
              console.log(voiceIt);
            } else {
              console.log(response.statusCode);
              console.log(body);
            }
          });

          twiml.say(
            'Welcome to the Voice Authentication system. You are a new user, ' +
            'you will now be enrolled.'
          );
          // Then we'll want to send them immediately to enrollment.
          twiml.redirect({ digits: '1' }, '/enroll');

          res.send(twiml.toString());
          break;
        default:
          new Error('An unhandled error occured');
      }
    }
  });
});

La experiencia será diferente en función de si el usuario se inscribe por primera vez o si se está autenticando.

La función /enroll, si se selecciona, se utiliza para crear una impresión de voz para el usuario. Deben decir la frase 3 veces para inscribirse.  Esta inscripción se guardará en VoiceIt y se comparará con /authentications (autenticaciones) futuras.

// Routing Enrollments & Authentication
// ------------------------------------
// We need a route to help determine what the caller intends to do.
app.post('/enroll_or_authenticate', function(req, res) {
  var digits = req.body.digits;
  var twiml  = new twilio.TwimlResponse();

  // When the caller asked to enroll by pressing `1`, provide friendly
  // instructions, otherwise, we always assume their intent is to authenticate.
  if (digits == 1) {
    twiml.say(
      'You have chosen to create a new account with your voice. You will be ' +
      'asked to say a phrase 3 times, then you will be able to log in with that phrase.'
    );
    twiml.redirect('/enroll');
  } else {
    twiml.redirect('/authenticate');
  }

  res.send(twiml.toString());
});

app.post('/process_enrollment', function(req, res) {
  var caller       = callerCredentials(req.body);
  var enrollCount  = req.query.enrollCount;
  var recordingURL = req.body.RecordingUrl + ".wav";
  // Prepare options for the VoiceIt `POST /sivservice/api/enrollments/bywavurl API request.
  var options      = {
    url: 'https://siv.voiceprintportal.com/sivservice/api/enrollments/bywavurl',
    headers: {
      'VsitDeveloperId' : VOICEIT_DEV_ID,
      'VsitEmail'       : caller.email,
      'VsitPassword'    : caller.password,
      'VsitwavURL'      : recordingURL
    }
  };

  request.post(options, function (error, response, body) {
    var twiml = new twilio.TwimlResponse();

    if (!error && response.statusCode == 200) {
      var voiceIt = JSON.parse(body);

      if (voiceIt.Result == 'Success') {
        enrollCount++;
        // VoiceIt requires at least 3 successful enrollments.
        if (enrollCount > 2) {
          twiml.say(
            'Thank you, recording recieved. You are now enrolled. You can log in.'
          );
          twiml.redirect('/authenticate');
        } else {
          twiml.say(
            'Thank you, recording recieved. You will now be asked to record your phrase again.'
          );
          twiml.redirect('/enroll?enrollCount=' + enrollCount);
        }
      } else {
        twiml.say('Sorry, your recording did not stick. Please try again.');
        twiml.redirect('/enroll?enrollCount=' + enrollCount);
      }
    } else {
      twiml.say('Sorry, your recording did not stick. Please try again');
      twiml.redirect('/enroll?enrollCount=' + enrollCount);
    }

    res.send(twiml.toString());
  });
});

La ruta /authenticate es el núcleo del sistema de autenticación de voz real.  Cuando un usuario llegue a esta sección, dirá su frase de Twilio y la grabación de Twilio se enviará a VoiceIt para que coincida con su inscripción.

Si coincide, se mostrará un mensaje simple “Great Success!” (Gran éxito), y se reproducirá un archivo JSON de VoiceIt, que indicará el porcentaje de coincidencia de autenticación. En una aplicación real, esto seguiría a la siguiente función; por ejemplo, permitirle acceder a su saldo bancario, etc.

Y eso es todo. La máquina ahora reconoce su voz.  Y yo, personalmente, le doy la bienvenida a nuestros nuevos líderes robots.

El código también está disponible en GitHub:

https://github.com/voiceittech/voiceit-ivr-demo

app.post('/authenticate', function(req, res) {
  var twiml = new twilio.TwimlResponse();

  twiml.say('Please say the following phrase to authenticate.');
  twiml.pause(1);
  twiml.say('Never forget tomorrow is a new day.');
  // We neeed to record a `.wav` file. This will be sent to VoiceIt for authentication.
  twiml.record({
    action    : '/process_authentication',
    maxLength : '5',
    trim      : 'do-not-trim',
  });

  res.send(twiml.toString());
});

app.post('/process_authentication', function(req, res) {
  var caller       = callerCredentials(req.body);
  var recordingURL = req.body.RecordingUrl + '.wav';
  var options      = {
    url: 'https://siv.voiceprintportal.com/sivservice/api/authentications/bywavurl',
    headers: {
      'VsitAccuracy'              : 5,
      'VsitAccuracyPassIncrement' : 2,
      'VsitAccuracyPasses'        : 4,
      'VsitConfidence'            : 87,
      'VsitDeveloperId'           : VOICEIT_DEV_ID,
      'VsitEmail'                 : caller.email,
      'VsitPassword'              : caller.password,
      'VsitwavURL'                : recordingURL
    }
  };

  request.post(options, function(error, response, body) {
    var twiml = new twilio.TwimlResponse();

    if (!error && response.statusCode == 200) {
      var voiceIt = JSON.parse(body);
      console.log(voiceIt);

      switch(voiceIt.Result) {
        case 'Authentication failed.':
          twiml.say('Your authentication did not pass. Please try again.');
          twiml.redirect('/authenticate');
          break;
        default:
          twiml.say("Great Success!");
          twiml.say(voiceIt.Result);
      }
    } else {
      twiml.say('API Error. Your authentication did not pass. Please try again.');
      twiml.redirect('/authenticate');

      new Error(response.statusCode, body);
    }

    res.send(twiml.toString());
  });
});

app.listen(port);
console.log('Running bioauthentication on port ' + port);

Este artículo fue traducido del original "Voice Biometric Authentication With Twilio". Mientras estamos en nuestros procesos de traducción, nos encantaría recibir sus comentarios en help@twilio.com - las contribuciones valiosas pueden generar regalos de Twilio.