I've been curious as to how google generates one time log in tokens on an iPhone app without comminicatig with the server when the token is Assigned. The token changes every ten seconds. How does google know what the right token is? I disabled data and it still works.
Thanks
it uses your unique key during setup as well as a special sequence/algorithm (that's part of the authenticator program (in your case, the iPhone .app)) to generate a special key. As part of the key-generating process, it also uses the current time on your iPhone to match up with the computer time you are logging in from.
remember a verification code, wait for the current code to expire, and continue logging into your google account on your computer with your previously memorized code. it will still work. try changing the time on your phone by 20 minutes off or something, and use a newly-generated code, it will not work.
it works similar to the HSBC security dongle keychain thinggy (for online banking) if you have one.
Google Authenticator generates OTPs based on the secret key. The secret key (seed) is 16 or 32 character alphanumeric code. In the process of token enrollment, the server generates the secret key and shares it with your phone via QR code (or you can enter it manually). For example, when TOTP algorithm is used, server and Google Authenticator know the seed and the current time and based on this information they generate the same one-time passwords (OTPs) at predetermined intervals. So the key elements are the secret key and time. Google Authenticator doesn’t require any internet connection or mobile network.
Related
I need to create a permanent identifying URL for each user, through which (by visiting it), they will be logged in.
For example:
User1: https://www.example.com/?userToken=gj56u45g64g56uy54g6uyg546
User2: https://www.example.com/?userToken=8o9k7ok9o89k7o9ko8k9o78k9
The functionality is similar how one would identify to an API, or click an email confirmation link, but it has to be permanent or at least with a very long duration, because it will be stored on an NFC chip.
How can I do this within Auth0? (or Oauth 2, because I think that's what they use?)
From some reading that I did, I did not seem to find a way to get a permanent token for a user, and those tokens that I could get, had a maximum life cycle of 24 hours, which is too short for the intended use.
I have done this fairly quickly in a custom way, but within Auth0 I am not sure how it's done.
I read about refresh tokens, but these it seems to me, will need to be written to the NFC chip every time, which I can't do.
When you authenticate, you are given an ID and access token.
You typically use the ID-token to create a long-lived session-cookie, that can live as long as you like. The ID-token is by design a pretty short-lived token, by default like 5 minutes in some systems.
If it is for an embedded system, then there also the device-flow, that is more suitable for devices with a limited UI https://auth0.com/device-flow
I doubt writing JWT tokens from an authorization service is the right approach, as you have to remember that these services typically change/rotate their signing keys, so tokens issued for 6 months ago, might not be accepted today. And for example in a compromise and they are forced to change all their signing-keys, then all your devices will be made useless.
Better approach is to write your own "key" into each device.
I have been reading about securing REST APIs and have read about oAuth and JWTs. Both are really great approaches, but from what I have understood, they both work after a user is authenticated or in other words "logged in". That is based on user credentials oAuth and JWTs are generated and once the oAuth token or JWT is obtained the user can perform all actions it is authorized for.
But my question is, what about the login and sign up apis? How does one secure them? If somebody reads my javascript files to see my ajax calls, they can easily find out the end points and the parameters passed, and they could hit it multiple times through some REST Client, more severely they could code a program that hits my sign up api say a thousand times, which would be create a thousand spam users, or they could even brute force the login api. So how does one secures them?
I am writing my API in yii2.
The Yii 2.0 framework has a buil-in filter called yii\filters\RateLimiter that implements a rate limiting algorithm based on the leaky bucket algorithm. It will allow you to limit the maximum number of accepted requests in a certain interval of time. As example you may limit both login and signup endpoints to accept at most 100 API calls within a 10 minutes interval of time. When that limit is exceeded a yii\web\TooManyRequestsHttpException exception (429 status code) will be thrown.
You can read more about it in the Yii2 RESTful API related documentation or within this SO post.
I didn't use it myself so far but from what I did read about it in official docs, and I mean this:
Note that RateLimiter requires
$user
to implement the
yii\filters\RateLimitInterface.
RateLimiter will do nothing if
$user
is not set or does not implement
yii\filters\RateLimitInterface.
I guess it was designed to work with logged in users only maybe by using the user related database table, the default one introduced within the advanced template. I'm not sure about it but I know it needs to store the number of allowed requests and the related timestamp to some persistent storage within the saveAllowance method that you'll need to define in the user class. So I think you will have to track your guest users by IP addresses as #LajosArpad did suggest then maybe redesigning your user class to hold their identities so you can enable it.
A quick google search let me to this extension:yii2-ip-ratelimiter to which you may also have a look.
Your URLs will easily be determined. You should have a black list of IP addresses and when an IP address acts suspiciously, just add it to the black list. You define what suspicious is, but if you are not sure, you can start with the following:
Create something like a database table with this schema:
ip_addresses(ip, is_suspicious, login_attempts, register_attempts)
Where is_suspicious means it is blacklisted. login_attemtps and register_attempts should be json values, showing the history of that ip address trying to log in/register. If the last 20 attempts were unsuccessful and were within a minute, then the ip address should be blacklisted. Blacklisted ip addresses should receive a response that they are blacklisted whatever their request was. So if they deny your services or try to hack things, then you deny your services from them.
Secure passwords using sha1, for example. That algorithm is secure-enough and it is quicker than sha256, for instance, which might be an overkill. If your API involves bank accounts or something extremely important like that, important-enough for the bad guys to use server parks to hack it, then force the users to create very long passwords, including numbers, special characters, big and small letters.
For javascript you should use OAuth 2.0 Implicit Grant flow like Google or Facebook.
Login and Signup use 2 basic web page. Don't forget add captcha for them.
For some special client such as mobile app or webServer:
If you sure that your binary file is secure, You can create a custom login API for it. In this API you must try to verify your client.
A simple solution, you can refer:
use an encryption algorithm such as AES or 3DES to encrypt password
from client use a secret key (only client and server knows about it)
use a hash algorithm such as sha256 to hash (username + client time + an other
secret key). Client will send both client time and hash string to
server. Server will reject request if client time is too different
from server or hash string is not correct.
Eg:
api/login?user=user1&password=AES('password',$secret_key1)&time=1449570208&hash=sha256('user1'+'|'+'1449570208'+'|'+$secret_key2)
Note: In any case, server should use captcha to avoid brute force attack, Do not believe in any other filter
About captcha for REST APIs, we can create captcha base on token.
Eg.
For sign up action: you must call 2 api
/getSignupToken : to get image captcha url and a signup token
respectively.
/signup : to post sign up data (include signup token and
captcha typed by user)
For login action: we can require captcha by count failed logins base on username
Folow my api module here for reference. I manager user authentication by access token. When login, i generate token, then access again, client need send token and server will check.
Yii2 Starter Kit lite
I'm designing a mobile app in which the client app that the user downloads simply opens their browser and opens the web app I designed. The web app should never be accessible except through the downloaded app. Before I put the site out there, I want to implement the authentication so people can't get to it until I release it.
The web app is Azure/C#/MVC5/Javascript/Sql Server. The launch program will differ by platform (Android/iPhone/Windows8Phone).
What I would like to do, if possible, is to implement authentication without requiring a password in order to lessen the burden on the user. I'm not very concerned from a security standpoint. The main purpose of the authentication is just to verify that the user did in fact buy the app and that they're not just browsing to the site.
I had assumed this part would be easy, but I've spent many hours searching for a solution and I'm much more confused than when I started. From what I've read, it sounds like I may need a 'secret' or a 'nonce'. I have no idea how to implement such things. Basically, I'm looking for two things here- confirmation that I'm marching down the right path from someone who knows this area (or a course correction if not), and perhaps a link to a site that contains actual implementation details for the appropriate solution.
Thanks in advance!
You need to have a secret on your client that the web backend can verify.
Passing the Secret for verification
You may just pass the secret to the web backend using REST like: http://web.app.com/something?secret=XXXXXX
If the secret checks out, you may redirect the client to the appropriate page.
Creating a Secret
It can just be any string you want, very much like a password you create.
More secure secret
You can generate a secret to pass to your web backend that is different each time by doing this:
secret = <random string> + SHA-1(<random string> + <fixed string>)
Javascript Library for SHA-1
Note: <fixed string> is up to you to define, this is the "real" secret that only people that have access to your code will know. (Of course they can disassemble your program and/or watch its running memory space to find out, but that's beyond most)
Testing the secret
On your web backend, split the given secret into <random string> and the SHA-1 parts. Then do SHA-1(<random string> + <fixed string>) (the fixed string is the same on both your client and backend). If the SHA-1 result is the same, it's verified!
Preventing Sharing
A user may still share the secret with others, to prevent that, we can introduce a time stamp in the <random string> giving <random string> + <time stamp>. With that, we can limit the validity of the secret to a particular time. In this case, 30 secs to a few minutes might do to accommodate Internet lag and inaccurate clock on the client.
We are currently tasked with implementing a (preferably simple) authentication system for a mobile application communication with a RESTful API. The backend has user-specific data, identified by the user's phone number. I am trying to understand more about security in general, the different methods there are and why they work the way they work.
I thought of a simple authentication system:
The client sends a verification request to the api which includes their phone number and a generated guid.
The server sends an SMS message to the phone number with a verification code.
The client verifies their device by sending their unique guid, phone number and verification code.
The server responds with some kind of access token which the client can use for further requests.
I have the following questions:
Are there any major flaws in this approach?
Assuming we use HTTPS, is it secure enough to send the data otherwise unencrypted?
Can access tokens be stored on mobile devices safely so that only our app can read them?
Anything else we haven't thought of?
We already figured that when the mobile phone is stolen or otherwise compromised, the data is no longer secure, but that is a risk that is hard to overcome. Access tokens could be valid temporarily to minimize this risk.
I am assuming this approach is way to simple and there is a huge flaw somewhere :) Can you enlighten me?
There is a flaw. The system is susceptible to a brute-force attack.
Suppose I am an attacker. I will generate a guid for myself and send it along with some arbitrary phone number.
Next, I will just bruteforce my way through the possible SMS codes - if it's 6 digits, there's only 10^6 combinations. The bruteforce will be a matter of seconds - and then I will gain acess to the data of the person having this phone.
Also, as was pointed out in the comment by Filou, one can force you to send you arbitrary number of SMS, effectively making you sustain a financial loss at no cost.
There's also no valid defense from this attack:
If there is limited amount (N) of attempts for a given UID, I will
re-generate the guid every N attempts.
If there's a limit of requests per phone per amount of time, I can execute a DoS/DDoS attack by flooding every possible number with fake requests - hence, noone will be able to perform any requests.
A login/password or certificate authenication is mandatory before an SMS. Also:
Never use things like GUID in cryptography/security protocols. GUIDs are deterministic (i.e., knowing one value, you can predict future ones). Use crypto-libraries built-in functions for generating random streams
Never try to design security protocols yourself. Never. There's an awful lot of caveats even SSL 1.0 creators fell to - and they were sharp guys, mind you. Better copy common and proven schemes (Google's auth is a great example).
The approach you mentioned will works fine. Client will initiate a request with the phone number and a random id, server returns a verification token to the device. The token is one time use only with a set expiry. Then client will send the phone number, the random token used before and the validation token, which the server verifies. If valid, server sends a session token (or auth token) or similar which can be used for authentication. The session token can have a time out set from the server.
You did not mention if it's a web app or not. If it's a web app, you can set a https only session cookie from the server. Otherwise, you can store it locally in the app's local store. In usual case, apps cannot read private data belonging to other apps.
All communications must take place using HTTPS. Otherwise the whole scheme can get compromised via sniffing for traffic, because in the end you are using the auth token.
Token cards display a number that changes periodically, perhaps every minute. Each such
device has a unique secret key. A human can prove possession of a particular such device by
entering the displayed number into a computer system. The computer system knows the
secret keys of each authorized device. How would you design such a device?
I believe this kind of authentication scheme is part of "two-factor authentication". In many popular 2FA solutions the user owns a small calculator-size device with a preconfigured PIN key. Upon entering the PIN, a One time password (OTP) is generated.
By entering the generated password, associated with his username, the user "proves" he has the device and knows the PIN code. Aladdin's safeword is such a device, popular in corporate/VPN/WifiPEAP environments.
It's also nowadays centralised and OTP are now often sent through SMS.
If you google around for the "How to implement two-factor authentication", you'll find numerous good articles. The topic is complex and involves many different technologies.
You can try this article for instance.
In the token device:
A stable clock with maximum deviation of 10s/year (can be done using quartz crystal oscillator), synchronized to UTC.
A public key stored individual to each device
Some random saltID, which also serves as the user identification value, so it should have reasonable length
A hash function
The number the token shows is generated by combining the saltID with the current time, hashing the value and encrypting it with the public key.
Upon login the authentication system reperforms the steps of the authentication token, minus of the public key encryption (i.e. it just computes the hash). The crypted hash is decrypted and compared to the calculated hash. If both match the token is accepted as valid.
The better authentication tokens have some numeric input, where the user can enter his PIN code, for protecting against loss or theft.