对于我们的共享秘钥,我们在用户开始TFA设置时分配了一个GUID。该GUID被Base-32编码,并放入URL中,该URL将转换为QR代码,并由用户使用手机扫描:
otpauth://totp/myapp_user?secret=g5swmnddhbtggllbgi3dsljumi3tallbmuytgljtg5sdgnbxmy2dgyjwmy======
我们尝试过所有非iOS设备,都能正常运作。但是在iOS设备上,大多数情况下尝试扫描条形码时会出现一个非常奇怪的错误:
Invalid barcode
The barcode '[same as above]' is not a valid authentication token barcode.
它符合Google/RFC 4226的最小秘密要求(128位),经过适当的Base32编码等...为什么会失败?这个消息通常出现在url中存在空格(但实际上并没有)的情况下。
如果我在guid的开头添加一个小种子,一切都正常运行:
otpauth://totp/myapp_user?secret=nfygq33omvzxky3lom3ggmzyha2tgnjnmu4gezbngqzdgyrnhbtdqzrnmeywimrwmjsgknzymi3a
基本上,这是以下两者之间的区别:
secret = enc.Encode32(Encoding.ASCII.GetBytes("iphonesucks" + Guid.NewGuid().ToString())); // Works
secret = enc.Encode(Encoding.ASCII.GetBytes(Guid.NewGuid().ToString())); // Fails
newAuthUrl = string.Format("otpauth://totp/myapp_user?secret={0}", secret);
我有两个关于为什么这可能起作用的疯狂理论:
- ios端口需要超过128位。 我的评论/种子足以将其推动到该限制之上,无论它是什么...除非我实际上给了它更多超过128位,因为它是一个guid-as-string。
- 在Base32解码之后,ios应用程序将秘密字符串识别为guid,并对其进行其他处理。