我正在深入研究Apple的Touch ID,更准确地说是本地身份验证器。 截至目前的文档非常稀少。 它主要是这个:
LAContext *myContext = [[LAContext alloc] init];
NSError *authError = nil;
NSString *myLocalizedReasonString = <#String explaining why app needs authentication#>;
if ([myContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&authError]) {
[myContext evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
localizedReason:myLocalizedReasonString
reply:^(BOOL success, NSError *error) {
if (success) {
// User authenticated successfully, take appropriate action
} else {
// User did not authenticate successfully, look at error and take appropriate action
}
}];
} else {
// Could not evaluate policy; look at authError and present an appropriate message to user
}
取自https://developer.apple.com/documentation/localauthentication
使用指纹进行身份验证的想法很不错。但如果我知道密码,我可以在设备中添加指纹。它很容易得到密码,就像你坐在受害者旁边的火车上,看着他/她输入密码。
我想将指纹用作安全身份验证的一种方式,但希望能够检测自上次请求指纹以来是否添加了新指纹。
Apple正在为AppStore做这件事。如果您想在AppStore中验证事务并且自上次事务以来添加了新的指纹,则AppStore会请求您的AppleId-Password。这是理智的行为,因为手机可能是由知道密码的其他人带来的,并添加了自己的指纹来购买昂贵的东西。
我的问题:我可以检测自上次使用本地身份验证器以来是否添加了新指纹?
答案 0 :(得分:18)
现在可以在iOS9中使用。已将evaluatePolicyDomainState属性添加到LAContext。
如果修改了指纹数据库(添加或删除了手指),evaluatePolicyDomainState返回的数据将会更改。无法确定更改的性质,但通过在不同的evaluatePolicy调用之后比较evaluatePolicyDomainState的数据,您可以检测到指纹集已被修改。
请注意,仅当调用evaluatePolicy并执行成功的Touch ID身份验证或canEvaluatePolicy成功执行生物识别策略时,才会设置此属性。
答案 1 :(得分:10)
正如Keith所说,在iOS 9中它是可能的。你应该这样做。
let context = LAContext()
context.canEvaluatePolicy(.DeviceOwnerAuthenticationWithBiometrics, error: nil)
if let domainState = context.evaluatedPolicyDomainState
where domainState == oldDomainState {
// Enrollment state the same
} else {
// Enrollment state changed
}
每次添加或删除指纹时,域状态都会发生变化。您需要致电canEvaluatePolicy
evaluatedPolicyDomainState
进行更新。
答案 2 :(得分:5)
总之;号
更详细一点; LocalAuthentication
框架是一个严密保护的黑匣子。您从中获得的信息非常有限。你与它的互动是这样的:
您没有实际身份验证过程的概念(例如,使用了哪个手指)。当然,这是设计上的。 Apple不希望也不需要让您访问此类信息。
答案 3 :(得分:3)
这是objective-c中的代码,用于验证是否添加或删除了指纹:
- (void)evaluatedPolicyDomainState {
LAContext *context = [[LAContext alloc] init];
__block NSString *message;
// show the authentication UI with reason string
[context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics localizedReason:@"Unlock access to locked feature" reply:^(BOOL success, NSError *authenticationError) {
if (success) {
// load the last domain state from touch id
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData *oldDomainState = [defaults objectForKey:@"domainTouchID"];
NSData *domainState = [context evaluatedPolicyDomainState];
// check for domain state changes
if ([oldDomainState isEqual:domainState]) {
message = @"nothing change.";
} else {
message = @"domain state was changed!";
}
// save the domain state that will be loaded next time
oldDomainState = [context evaluatedPolicyDomainState];
[defaults setObject:oldDomainState forKey:@"domainTouchID"];
[defaults synchronize];
} else {
message = [NSString stringWithFormat:@"evaluatePolicy: %@", authenticationError.localizedDescription];
}
[self printMessage:message inTextView:self.textView];
}];
}
答案 4 :(得分:1)
我建议将 evaluatePolicyDomainState 值存储到钥匙串中,而不是将其存储在 NSUserDefault 中。
您可以将 evaluatePolicyDomainState 的数据值转换为字符串,这是一个44个字符的字符串。下面是将 evaluatePolicyDomainState 数据值转换为字符串的代码 -
Content
现在,如果设备所有者在Touch ID中进行了任何更改,例如添加新的手指ID;然后,此数据值将被更改,您可以根据项目需要采取必要的步骤来处理更改。
答案 5 :(得分:0)
我想补充一些内容,
-(BOOL)hasFingerPrintChanged
{
BOOL changed = NO;
LAContext *context = [[LAContext alloc] init];
[context canEvaluatePolicy:LAPolicyDeviceOwnerAuthentication error:nil];
NSData *domainState = [context evaluatedPolicyDomainState];
// load the last domain state from touch id
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData *oldDomainState = [defaults objectForKey:@"domainTouchID"];
if (oldDomainState)
{
// check for domain state changes
if ([oldDomainState isEqual:domainState])
{
NSLog(@"nothing changed.");
}
else
{
changed = YES;
NSLog(@"domain state was changed!");
NSString *message = @"Your Touch ID is invalidated, because you have added or removed finger(s).";
}
}
// save the domain state that will be loaded next time
[defaults setObject:domainState forKey:@"domainTouchID"];
[defaults synchronize];
return changed;
}
将用户密码等存储在钥匙串中会更好。 我正在使用https://github.com/reidmain/FDKeychain