服务器上的Cordova指纹认证

21

我正在尝试为我的(cordova)Android应用程序创建一种身份验证机制,使我的用户可以使用密码和用户名进行登录,或者允许他们扫描指纹以便登录。

如何在客户端和服务器端上验证已注册的指纹?使用Cordova是否可能实现?我尝试将指纹扫描的结果传输到我的服务器:看起来像这样:

FingerprintAuth.isAvailable(function(result) {
  if (result.isAvailable) {
    if(result.hasEnrolledFingerprints){
      FingerprintAuth.show({
        clientId: client_id,
        clientSecret: client_secret
      }, function (result) {
        alert(JSON.stringify(result));

        $http.post('http://192.168.149.33:3000/authorize', result).then(
          function(response) {}
        );

        if (result.withFingerprint) {
          $scope.$parent.loggedIn = true;
          alert("Successfully authenticated using a fingerprint");
          $location.path( "/home" );
        } else if (result.withPassword) {
          alert("Authenticated with backup password");
        }
      }, function(error) {
        console.log(error); // "Fingerprint authentication not available"
      });
    } else {
      alert("Fingerprint auth available, but no fingerprint registered on the device");
    }
  }
}, function(message) {
  alert("Cannot detect fingerprint device : "+ message);
});

服务器端我收到了以下数据(3个独立的扫描):

{ withFingerprint: 't8haYq36fmBPUEPbVjiWOaBLjMPBeUNP/BTOkoVtZ2ZiX20eBVzZAs3dn6PW/R4E\n' }
{ withFingerprint: 'rA9H+MIoQR3au9pqgLAi/EOCRA9b0Wx1AvzC/taGIUc8cCeDfzfiDZkxNy5U4joB\n' }
{ withFingerprint: 'MMyJm46O8MTxsa9aofKUS9fZW3OZVG7ojD+XspO71LWVy4TZh2FtvPtfjJFnj7Sy\n' }

每次指纹的模式似乎都不同,有没有办法将指纹与数据库中某个保存在用户下的模式进行关联?


我认为插件应该是这种实现方式的最佳选择。请查看此插件 - https://github.com/mjwheatley/cordova-plugin-android-fingerprint-auth - Gandhi
嗨,马克,我有一个疑问。如何获取客户端ID和客户端密钥? - HariKrishnan.P
@HariKrishnan.P 我认为你需要深入了解本地代码。或者你可以搜索一个 Cordova 插件,它可以与本地功能进行交互。 - Mark Stroeven
@Gandhi- 我已经使用了以上插件,但是我们在数据库中存储指纹的格式是字符串还是任何图像? - Kapil Soni
3个回答

14

简短回答

这个 API 返回的字符串不是“指纹模式”。因此,您不能按照您想要的方式进行认证。

详细回答

让我们首先看一下您正在使用的 API 的源代码

查看此文件,我们可以看到以下方法:

public static void onAuthenticated(boolean withFingerprint) {
    JSONObject resultJson = new JSONObject();
    String errorMessage = "";
    boolean createdResultJson = false;
    try {

        if (withFingerprint) {
            // If the user has authenticated with fingerprint, verify that using cryptography and
            // then return the encrypted token
            byte[] encrypted = tryEncrypt();
            resultJson.put("withFingerprint", Base64.encodeToString(encrypted, 0 /* flags */));
        } else {
            // Authentication happened with backup password.
            resultJson.put("withPassword", true);

            // if failed to init cipher because of InvalidKeyException, create new key
            if (!initCipher()) {
                createKey();
            }
        }
        createdResultJson = true;

// ...

/**
 * Tries to encrypt some data with the generated key in {@link #createKey} which is
 * only works if the user has just authenticated via fingerprint.
 */
private static byte[] tryEncrypt() throws BadPaddingException, IllegalBlockSizeException {
    return mCipher.doFinal(mClientSecret.getBytes());
}

看看被放置到"withFingerprint"中的内容。这是加密客户端密钥的Base64编码。从技术上讲,这就是您的身份验证。您将使用此令牌进行身份验证请求,服务器将解密和验证客户端密钥。

摘要

指纹识别增加了一层安全性,但并不是唯一的安全手段。必须事先建立设备和服务器之间的关系。

我发现这张图在理解Android指纹身份验证的意图方面很有帮助(参考:http://android-developers.blogspot.com/2015/10/new-in-android-samples-authenticating.html

enter image description here


非常感谢您! - Mark Stroeven
@MarkStroeven 没问题!我也学了一点关于指纹识别的知识 :) - souldzin
有用的信息。谢谢。只需添加上述图表的 Android 博客链接:https://android-developers.googleblog.com/2015/10/new-in-android-samples-authenticating.html - Tapash

1
你不能在服务器上验证指纹,指纹是使用“Live Scan /生物识别模板”进行存储或验证的。通过将当前扫描模板与先前存储的模板进行比较来进行身份验证。
首先,你无法访问这些存储的模板(不由操作系统提供程序/手机制造商提供),即使我们假设你可以访问这些模板,那么需要一种高效的算法(基于图像/基于模式)来将当前模板与先前存储的模板进行比较。你不能简单地通过字符串比较进行验证。

-1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接