Why Onvif authentication works only with disabled replay attack protection? - python-3.3

I am working on Onvif client in Python3.My authentication algorhitm is:
b64encode(sha1(b64decode(nonce.encode('utf-8')) + date_utc.encode('utf-8') + password.encode('utf-8')).digest())
Basically,
b64encode(sha1(b64decode(nonce)) + date + password)
I have also created ONVIF profiles and synchronized date and time on camera. What am I doing wrong?
And used camera is AxisQ1604, fw version 5.50.03

The same nonce can be used only once, than cameras (should) discard any other usernametoken that uses the same nonce.

Related

EMV Secure Messaging

I am working on a project which requires Secure Messaging of an EMV card to protect data sent to/received from EMV cards.
According to the EMV Book 3, section 6.3.2:
For my understanding, we can use 'Secure Messaging' on every command/response pair.
For example, we can use CLA='8C', INS='CA' for Secure Messaging Format 1, and CLA='84', INS='CA' for Secure Messaging Format 2
However, when I tried on two of my cards I got error 6E 00 -- Class not supported.
What's wrong with my understanding about the 'Secure Messaging'?
None of the current EMV protocols seem to support secure messaging. Consequently, your card/EMV applet won't support secure messaging either.
Also, I'm not quite sure what exactly you would want to use secure messaging for ... Excahnged information is already authenticated (under the assumption that you perform a transaction and that you do CDA/SDA/DDA). So you probably aim for encrypting the information exchanged between the terminal and the card (specifically things like the amount charged, static card data, etc.) However, I doubt that this would make much sense based on the design of the current EMV infrastructure:
Terminals are currently not assumed to be trusted (at least with regard to the EMV protocol exchange between the terminal and the card). Consequently, you won't be able to implement any form of mutual authentication between the terminal and the card. Only the terminal could authenticate the card, the card could authenticate information received from the issuer (e.g. issuer scripts), but the card could never authenticate the terminal. As a result, impersonation of the terminal side would be possible despite encryption. Hence, an attacker in the middle would still be able to read and decrypt messages.
From a comment by Michal Gluchowski:
Maybe to extend what Michael has said, where next generation EMV is planning to go is to introduce channel confidentiality to eliminate passive eavesdropping. It will, however be possible to impersonate terminals (only card certificates will be authenticated). Current EMV uses secure messaging only for issuer scripts as it requires symmetric secret key that is known to issuer only. From the transaction perspective all the data terminal exchanges are plaintext (and issuer scripts are simply passed through without terminal analyzing or modifying them).
Source regarding next generation EMV & channel security: Next Generation Kernel System Architecture Overview, EMV 2nd Generation, Version 1.0, Sept. 2014

How to make sure that only the authorized user can access a feature provided by the server?

We are building an android application and one of its features is to book a cab service provider's cab (say an Uber).
We have an application specific user ID. Let us call it AUID. To book the cab, the application would Post a request to server and send AUID along with other relevant information (like lat, long etc). How do I make sure at the server end that the request is indeed coming from the correct user and it is safe to book the cab? In the current form, if a third party gets to know the AUID of another person, the third party can book a cab on behalf of that person.
One of the solutions I thought of was using asymmetric encryption. The application would hold the public key and the server would contain the private key. Instead of sending the user ID to the server, we'll instead send an encrypted key where the key would be AUID + timestamp encrypted using the public key. We'll then decrypt the message using private key at server end to obtain the AUID. If the timestamp at server does not lie within a certain interval of the timstamp sent by the client, we reject the request.
Is this a safe enough approach? Is there any other practice widely followed for such scenarios?
What you propose is sensible: encrypt the AUID on the client app and verify on the server. As comments suggest, SSL is vital.
The problem is that if how to encrypt the AUID is in your app, it can be figured out by anyone dedicated enough.
You can drastically reduce the risks of fake requests by issuing a separate encryption key for each user. This means that if someone cracks your code, they can still only spoof from one account. However, once an attacker had decompiled your app, they could theoretically start new accounts, get a valid encryption key and spoof requests.
What you need for 100% reliability is some form of authentication which is not stored in the client app - like a password or TouchID on iOS or fingerprint api on Android M. So when a user orders a cab, they need to enter some piece of information which you also encode with the AUID and check on the server. That secret information is not stored in your app, so no-one can fake requests.
Requiring a password from a user is pretty inconvenient. Fingerprint scanning is much easier and probably acceptable. You could also use a trust system - if the user has ordered cabs before and everything was OK, they can order without special authentication. Using Trust together with individual encryption keys is pretty effective because anyone trying to spoof requests would need to do a successful order before being able to spoof - which is probably too much hassle for them.

Two - Step authentication, how does it work?

So as part of a project, I want to implement a two step authentication system (in rails)
I understand the principles of it,
=> Client: Username and password
<= Server: Generate PIN code and send it to client via SMS/email
=> Client: enter PIN
<= Server: authenticate client as normal
Now what I want to know is in a web based application such as rails, the PIN needs to be kept secret at every point, so when redirecting from the username/password part to the PIN part, I need to keep the PIN code secret while passing it over to the next part of the system (the PIN part)
Is the only decent way to do this, by temporarily storing the PIN in the database alongside a user ID?
No, not quite that.
There are two (most used) types of one-time passwords (OTPs, PINs in your terminology):
Time-based
Counter-based
Time-based ones (TOTP) generate some number based on current time (for example: number of 30-second intervals from 1970.1.1 00:00) and some shared secret. When receiving such one-time password, server generates one on its side and checks whether it's correct.
In counter-based OTPs, you have a counter and a secret key stored in database near user ID, and it is used to generate the OTP. It can be incremented based on login attempt.
Time-based tokens are usually better, as they don't require counter synchronization (time synchronization is usually easier). Best example of this is the Google Authenticator, which implements standard TOTP from RFC6238.
There's one Ruby OTP library which claims compatibility with Google Authenicator, you may want to try it out: link
Can't vouch for its security and/or quality, but it looks promising.

How to create a cryptographically secure authentication without requiring keyboard input?

I'm working on a system that will require a user to log in on a device using an account that they created on a website. Authentication will be over HTTPS, so that is not an issue. The application running on the device will allow in-app purchase using a credit card linked to their account, so it's important that the login credentials are secure enough that it would be difficult to attack using brute-force. The only problem is that the device that the user will be using will have limited user input capabilities (essentially, arrow keys and a selection button).
In this case, a typical username/password may be too cumbersome to enter, also requiring the development of a on-screen keyboard that is navigable via the arrow keys. Users would likely end up creating simple passwords that are easily cracked. However, once logged in, the user will be using an access token behind the scenes so they may not need to enter their password very many times.
The first step is that the user will need to enter their username or ID number. Using a number may be easier to enter, but also easier to guess. I'm open to suggestions in this area as well.
Next is the process of entering a "password". So here are a few ideas that I have, but I'm not a cryptography expert so I don't know how to gauge the level of security.
User must first register the device. This might be a step that I require anyway, for extra security. The device would generate a key that is sent to the server and stored with the account. The key would be required when performing future authentication requests. The user would need to log into the website to approve the device. The device isn't going to have any sort of identifier, so unless you log in soon you wouldn't know if it was your device or someone else trying to spoof you. It would be nice to be able to create some sort of additional identifier, maybe a short code, phrase, or an image is displayed so you can know it's the same device that you just tried to register.
Since entering a text password may be too difficult, as long as the device is registered, maybe a 4 digit passcode can be used when confirming in-app purchases. This may be nice anyway to prevent other users of the device from using your account without your permission. However, if they are watching you enter your passcode, then it's not really good for that purpose anymore.
If registering the device is not necessary, instead of logging in with a text password, maybe the user is presented with images or phrases as options and they must choose the right combination of images/phrases that matches their account.
That's all I've got so far. What are your thoughts? How can I create an easy, but secure, login when in-app purchases are involved?
I have been dealing with limited user input capability scenario. Would you describe the platform your app running on?It helps to fit the solution according to the platform security model.
Update: I hope you are not considering multi-user per device scenario. So, I am assuming that there is one user per device. The second assumption is the device may have a unique serial number that can be accessible through some APIs and the serial number is registered on the server in advance.
At the initial stage, the user generates a random key through the device select button and the app confirms the success of key generation probably it display the serial number (the user may need to register the serial number for latter configuration). Behind the scenes, the app sends the new key with its serial number to the server. The server updates its serial number with the random key in the database entry. The device can block further key generation or may allow until it is finally configured with a dedicated user. The device also persist the serial number with the random key in the local database/file. The user is then login to their account through a web interface to configure the device. For logged in user, the server presents a list of available devices and the user can choose a specific one that belongs to her/him and set four digit pin code. The server performs the following:
Link the user account, the serial number, the random key (the one the device sent at the beginning).
generate a token
generate a key using pin code and the random key as a salt through Password based key derivative algorithm (PBKDF2)
encrypt the token using the key derived at step 3
Update database user row with the cipher token.
The user can sync the cipher token through the device select button. To unlock the app, user must enter the pin code through a simple numeric screen. The app uses the pin code and a random key (persisted at the beginning) and generates a PBKDF2 key and decrypt the token. PBKDF2 helps us to slow down the brute force a bit but it is possible to enforce time based or attempt based lockout as well. For instance after some trail, the app can drop the user credentials and force the user to configure from the scratch.

Make an HTTP request non-replayable

I have an application that runs on for example Google TV or Apple TV, which sends HTTP requests to a service of mine.
Now if someone listens in on this request, they can replay it and in that way execute a Denial of Service (DOS) attack our service.
Is there any way to make each request unique, so it cannot be replayed?
I thought of sending the time encrypted in the request and check the difference between the server time and the time the request was sent, but I'm getting too big time differences to compare.
Does anyone have a better idea?
You are in a good situation as you have control both on the server side and the client side (your application is talking). Include into your message
The current time in milliseconds plus + random number
The combined hash produced by these values plus (as a the third input) some key only your application knows. Use some good one way hashing algorithm.
Only the code who knows the mentioned key will be able to compute a correct hash. The used request records (hash and time stamp) can be stored for some expiration time that can be long. Very old request records can be easily expired as they contain the time stamp.
The positive feature of the proposed approach is it does not require to connect in advance in order to receive a token, needs no authentication, needs no registration and can use the open protocol. Using token just by itself does not help much against DoS as an attacker quickly writes a script to connect and obtain the token in advance as well.

Resources