I need to develop a feature in the system which allows unregistered users to get one-off system access via URL token that is generated/sent by an authenticated user.
For example, a user logs in and wants to share a piece of information so the system generates a URL like http://host/page?token=jkb345k4b5234k54kh5345kb34kb34. Then this URL is sent to an unregistered user who would follow the URL to get some limited access to normally protected data.
First question - are there any standards (RFC? IETF? others?) that would be defining URL generation? The only ones I was able to find are RFC2289 and OpenToken, but none of these are directly related to what I need to do and the latter is only in a second draft state.
There is another design consideration: whether to use one way crypto hash functions and store the payload in a local data store VS using private-public key pairs and encode all necessary payload in the unique string itself.
At the moment I am heavily leaning towards one way hash as it would give me much more freedom (no dependency between payload size and generated string) and less potential problems in the future (e.g. what if I decide to add more payload - how to ensure backwards compatibility). Last but not least, accidental exposure of server-side private key would require massive efforts in key regeneration, update of all live instances, etc. None of these problems are relevant if choosing one-way hash option, but maybe there's something I overlook? RFC2289 prefers one way crypto function whereas OpenToken chooses the key pair option.
And finally, is anybody aware of any Java library for generating these?
Thanks in advance.
Also have a look at http://en.wikipedia.org/wiki/Universally_unique_identifier and RFC4122. Inside the backend you would need to attach the generated uuid to your entity so verification based on the UUID can be done later.
Apart from that most often the token could include some data (e.g. versioning+userdata) and then a secure MD5-hash is used to 'obfuscate/anonymize' it. Later then the data is concatenated by server and the hash-values are compared again.
Regarding java-lib and uuid have a look at UUID-javadoc.
Generate random strings and store them in a database with credentials.
The codes generated need to have two properties: complexity and uniqueness. Complexity ensures that they cannot be guessed and uniqueness ensures that the same code can never be generated twice. Beyond this, the specific method doesn't matter.
Generate token strings with two parts to them. The first part is time-dependent, where the key will increment and change in a predictable way with each millisecond. The second part is completely random. Combined, this will give you a long string that is unique and complex.
When you generate the token, store it in the database with the credentials that are granted when this token is used. It's important that these credentials are not encoded into the string, since this ensures that the strings cannot be hacked.
When the user click on the link with the token, mark that token as used in the database. Even better is to set a timestamp for the use, so that it can be expired, perhaps, 24 hours after the first click. This approach gives you the flexibility to implement this specific part of the requirement as necessary for your project.
I've used this solution before in many different cases for not only one-off system access, but also for ticket admission codes, gift certificate codes, and anything that's one-time use. It doesn't matter so much what you use to generate the token, so much as you can guarantee its complexity and uniqueness.
Here's how I would have done it:
Create a token (you could use a UUID for this) and add it to your database along with creation time and what resource the token should grant access to
Send an email to the user with the url http://www.myserver.com/page?token=
When the user navigates to the url, create a new session with the desired timeout and mark that session as authorized to view whatever the database says the user should be able to see (If the token isn't too old. Check the creation time against current time)
Either delete the token from the database, or mark it as expired
You only need a token when a user shares one piece of information. So, can't you just generate a random token, and associate this with the piece of information (e.g. a database field)? It's a lot simpler than doing any crypto stuff...
Related
I am looking for a way to generate IDs (a sequence of bytes) which I can (in some way) verify to be generated by my application.
I am currently using AES-GCM for this purpose which encrypts some random input. When receiving these AES-GCM IDs I am trying to decrypt them, if it fails I know it wasn't generated by me. But having a static encryption key that will probably never change in the future (as I would have to redistribute all generated IDs) is (as I understand it) a problem with GCM as it gets less secure whenever a nonce is reused which is bound to happen at some point.
Another approach I have in mind would be to generate a pair of (plain_text_id,hmac(plain_text_id, secret)) as the plain_text_id is some random generated id which I internally map to a real user id (it's thus useless to an attacker). This is the same as signing some plain-text.
I do not want to check against a database as I explicitly want to employ this sanity check before hitting the database (so that e.g. a random attacker cannot DDoS me with random id's)
Is there another approach for generating verifiable id's? Is using AES-XXX or a HMAC approach (like outlined above) sufficient? And if so: which one and why?
I went through many posts on stackoverflow to find how to create a simple web token to confirm a sign up via mail. Without seeing any "official" manner or common technics.
My though was instead of adding a specific cell in database with expiry date to encrypt or hash the expiry date , the email and a random value (generated with randomSecure) to create my token.
Is this the good manner to achieve that? are there library to automatically do that.
Any help is greatly appreciated.
You (probably) need a way to prevent someone from generating their own tokens. If your token has the expiry date and email address in clear in the token, then they can be reverse engineered with little effort, so the only secure information is the random number. But in order for the random number to be useful (from a security perspective), your server needs to remember the random number. But if you are going to do that, the other information is redundant.
So my suggestion is to just use the random number as the token. And a good way to generate a random number with suitable "text armor" is to generate a type-4 UUID; see the UUID class javadoc for details. The rest of the information (the expiry, the email address and the unique key for the user's registration info) can be stored in a database table and not sent to the user.
I want to build an app which shows places around user using Google Places based on user interests. As mentioned here:
Place IDs are exempt from the caching restrictions stated in Section
10.5.d of the Google Maps APIs Terms of Service. You can therefore store place ID values indefinitely.
So, can I save place_id in cloud database and perform any analytics operation over it? For example; if I gather place_ids added in each user's favorite places table and from analytics; I can know which place_id are the most ones added to favorites? or can I show something like 'Trending Places' in app from gathered place_ids in responses?
Will it violate the terms and conditions? I read the whole page of terms but couldn't find the answer.
can anyone help me out? Thanks.
Yes you can 100% store the place_id indefinitely and reuse it.
See Referencing a Place with a Place ID.
Please note one thing that
A single place ID refers to only one place, but a place can have
multiple place IDs
These terms and conditions are kind of self explanatory. Except your requirement which will be clarified after the below link is read carefully. As per your requirement , inorder to prevent calling services next time with same query which user had done with an intention of saving network calls is acceptable.
No caching or storage: You will not pre-fetch, cache, index, or store any Content to be used outside the Service, except that you may store limited amounts of Content solely for the purpose of improving the performance of your Maps API Implementation due to network latency (and not for the purpose of preventing Google from accurately tracking usage), and only if such storage
1) is temporary (and in no event more than 30 calendar days)
2) is secure 3)
does not manipulate or aggregate any part of the Content or Service 4) and
does not modify attribution in any way. Go through this Section 10.5 Intellectual Property Restrictions. Subsection (B)
You'll need to contact Google to get a 100% answer.
That being said, from my experience it looks like the clause you included is intended exactly for the kind of thing you want to do.
Again, I want to reiterate that contacting Google directly is something you should do if you still have concerns.
You can store place ID values indefinitely.
Just What part of
You can therefore store place ID Values indefinitely.
Don't you understand?
Indefinitely requires a server.
I have a little GAE application, a backend for my Android app.
I have a servlet in the app that pulls data from the datastore and send it to the user.
I don't want anyone to be able to use this servlet, so I store a private key in the app, and for every request I'm sending a token - a hash string of the private key and the current milliseconds, and the milliseconds I've used in the hash.
The server is taking the milliseconds and the private key, and comparing it with the token. If it went well, the server is storing the milliseconds in a HashSet so it will know not to use it again. (Someone can sniff the device data - and send the same milliseconds and token over and over again).
At first, I held a static field in the Servlet class, which was later discovered as mistake, because this field is not persisted, and all the data is getting lost when the instance get destroyed.
I've read about Memcache, but it's not an optimal solution because from what I understand, the data in the Memcache can get erased if the app is low on memory, or even if there are server failures.
I don't want to use datastore because it will really make the requests much slower.
I guess I'm not the first who is facing the problem.
How can I solve it?
I used a reverse approach in one of my apps:
Whenever a new client connects, I generate a set of three random "challenges" on the server (like your milliseconds), which I store in memcache with an expiration time of a minute or so. Then I send these challenges to the client. For each request that the client makes, it needs to use one of these 3 challenges (hashed with aprivate key). The server then deletes the used challenge, creates a new one and sends it to the client. That way, each challenge is single-use and I won't have to worry about replay-attacks.
A couple of notes on this approach:
The reason I generate 3 challenges is to allow for multiple requests in flight in parallel.
The longer you make the challenge, the less likely it will be that it will be randomly reused (allowing for a playback attack then).
If memcache forgets the challenges I stored, the app's request will fail. In the failure, response I include a "forget all other challenges and use these 3 new ones: ..." command.
You can tie the challenges to the client's IP address or some other sort of session info to make it even less likely that someone can "hack" you.
In general, it's probably always best to have the server generate the challenge or salt for an authentication than giving that flexibility to the client.
Another approach you could use if you would like to stick with using a timestamp is to use the first request interchange to determine the time offset between your server instance and your client device. Then, only accept requests with a "current" timestamp. For this, you would need to determine the uncertainty with which you can get the time offset and use that as a cutoff for a timestamp not to be current. To prevent replay-attacks within that cutoff period, you might need to save and disallow the last couple of timestamps used. This, you can probably do inside your instance since AppEngine, AFAIK, routes requests from the same client preferentially to the same instance. Then, if it takes longer to shut down an instance and restart one (i.e. to clear your disallow cache) than your "current"-cutoff is, you shouldn't have too many issues with replay-attacks.
I have a project to build a voting desktop application for a class in Java. While security isn't the focus of the project, I would like to be as realistic as I can. What are some of the primary tools to integrate security into a Java application.
Edit: I'm not primarily worried about physical security, we are simply building an application not a whole system. I want to ensure votes are recorded correctly and not able to be changed or read by someone else.
It really depends on what kind of security you are looking to integrate. Do you want security to ensure that the user isn't running any debuggers or such to flip bits in your application to change the votes? Do you want to ensure that the user doesn't install logging software to keep track of who voted for who? Do you want to ensure that the person who is supposed to be voting is actually voting? Security is a very broad subject, and it's hard to give an answer without knowing what exactly you are looking for.
My company did lately app with very strong security. Maybe it helps.
Our app
It was java EE app.
Architecture is following:
Client computer has a cryptography package.
Dirty serwer that stores encrypted user input and output
Clean serwer that is not accesible from outside that stores keys and decrypted data.
Users are issued cryptography cards (you may want to use something less safe - eg. pgp), and are required by jsp pages to encrypt with them all input. Page contains component that connects to cryctography app, asks user for key passphrase, encrypts it with server public key and signs it with user private key, then submits.
Data is stored in external server then transferred to internal server, where it is decrypted and signature is verified, then data is processed and reencrypted, then it is sent to dirty server, and then user may get it.
So even if someone cracked the dirty server (even get hold of database) he would get mostly useless data.
Your app
I'd send encrypted and signed votes to server. It would assert two things:
You know who sent the vote
Noone wil be able to know what the vote was.
Then get data from server, assert that everyone voted at most once count the votes, voila!
If you're looking for a "higher-level" explanation of this stuff (as in, not code), Applied Cryptography has quite a few relevant examples (and I believe a section on "secure elections" that covers some voting strategies).
I'm not primarily worried about physical security, we are simply building an application not a whole system. I want to ensure votes are recorded correctly and not able to be changed or read by someone else.
Putting to one side questions of protecting against physical tampering (e.g. of the underlying database), since you've stipulated that physical security is not the present concern...
I think the primary consideration is how to ensure that a given voter votes only once. At a paper poll, each registered voter is restricted to a particular booth/location and verification is done by name+SSN and a signature.
You might need a high resolution digital signature capture and therefore a touchscreen capture peripheral or a touch screen terminal. A more sophisticated approach would be a biometric scanner, but that would require government records of thumb/finger prints or retinal scan - I can already see the privacy advocates lining up at the lawyer's offices.
Another approach would be for the voter "registrar office" to issue digital keys to each voter prior to the election - a (relatively) short (cryptographically strong) random alpha/numeric key that is entered with the voter's name and/or SSN into the application. Knowledge of that key is required for that particular voter in that particular election. These keys would be issued by post in tamper-evident envelopes, like those used by banks for postal confirmation of wire transfers and delivery of PIN numbers. The key must include checksum data so that the user can have the entry of it immediately validated and it should be in groups of 4, so something like XXXX-XXXX-XXXX-CCCC.
Any other "secret" knowledge, such as SSN, is likely too easily discovered for a large percentage of the population (though we don't seem to be able to make credit-granting organizations understand this), and therefore is unsuitable for authentication.
Vote counting can be done by generating a public key encrypted data file which is transferred (by sneaker net?) to the central system. This must include the "voting booth" identity information and a record for each voter including their SSN and the digital key (or signature, or biometric data). Votes with invalid keys are eliminated. Multiple votes with the same key and same votes are treated as a single vote for that candidate. Multiple votes with the same key and different votes are flagged for fraud investigation (with the constituent contacted by phone, issued a new key, and directed to revote).
Your problem is that you need to identify the user reliably, so that you can prevent them from re-voting and accessing each others votes.
This is not any different from any other desktop application that requires authentication (and potentially authorization). If your voters are a closed group on a network with user accounts, you could integrate with the directory and require users to log in.
If voters do not have network user accounts, this is where it gets interesting. Each user will still need to authenticate with the application. You could generate accounts with passwords in the application and distribute this information securely prior to voting. Your application could ask users to select a password when the access the application for the first time.
Without knowing the specifics, it is hard give a more specific answer.
You are aware that electronic voting is an unsolved research problem? Large scale fraud should take a large effort.
I believe that physical security is more important for voting booth system rather than you know, code security.
These machine by their very nature shouldn't be connected to any kind of public networks, especially not the the internet. But having a good physical security to prevent any sort of physical tampering is very important.