I'm currently trying to come up with an authentication process for an Android app, that talks with web backend using REST. At the moment the communication is secured by TLS (with cert pinning) and auth tokens - former makes the client trust the server, latter allows client to make calls to the server's API. Auth tokens are given to the client if a user registered in the system successfully authenticates with login/password within the app. The user doesn't have to re-authenticate between the runs of the app, unless they manually choose to log out at some point.
It's easy to see that in a scenario where user gets his device stolen, the attacker can easily impersonate them, so it would be nice to introduce an additional authentication measure for security-critical operations. For UX-related reasons, I cannot ask the user to re-authenticate with login/password. I can however use a typing-friendly secret, like 6 digit PIN, and a limited number of authentication attempts.
My first idea was based on Android-specific cryptography (Keystore). Generate an ECDSA or RSA key on the device, then register the public key in backend's database. When security-critical operation comes, do a challenge-response, where client proves it has the private key corresponding to the registered public one. Unfortunately, Android platform doesn't allow the developer to have per-application access control to the keys stored on the device. Access control to Android Keystore is based on system-wide credentials used to unlock the device (pattern/pin/biometrics), and unfortunately I cannot rely on them. I also cannot safely implement my own PIN check within app, because that can be bypassed with a debugger.
My second idea is to authenticate user's PIN with SRP protocol, with backend keeping track of authentication attempts. From what I have read, it's a widely implemented solution in the industry. However, it seems to me that it has been designed with different things in mind, so I'm not sure how well it would fit my purpose. For example, in the first step of the protocol, server returns salt to the client. I assume that's because the 'client' in SRP can be a web browser, and user can use any browser from any device, so you can't really expect the client to have anything except his password. In my scenario, mobile app is supposed to be an entity within the system and one of the user's authentication factors (something the user has - the auth token). So I might as well store the salt on the device, especially since in case of server's database leak, when all the verifiers and salt values get public, 6 digit PINs can be easily dictionarized.
The other thing is, I already have TLS as a measure to authenticate the server, and I don't need the shared key for much, since the session effectively ends when the server is convinced the user entered proper PIN.
I would like to ask, if you think the SRP protocol is a good solution to my problem, what should I take into account, and if there are better alternatives.