I'm in the process of learning Django, and I'm building an app that has a "User" model, and I need to store a dictionary of private API keys for various other applications for each user, where the key is the service name and the value is the actual API key. My current plan was to have the dictionary be stored as JSON, but I was wondering if there is a better/more secure way I should be doing this?
1) Use a extra Model with 1to1 relation to the default Django User Model (extendable, nicer)
2) Use a hashfield to secure the data
See https://github.com/amcat/django-hash-field
djangomachine is right. Hashing is not the answer because you need to use the actual key at some point.
You need to encrypt the key upon storage and decrypt the key upon retrieval. Look into https://github.com/incuna/django-pgcrypto-fields for example.
Related
This is an assignment.
I have to create a web application on the google app engine and apply the rsa algorithm for storing data on the app engine datastore. My application just stores small notes created by the user. I have finished the application and also applied RSA for encrypting the messages (got code from Implementing RSA algorithm). For that I split the string and convert each character to an ascii and then store them in a repeated ndb.IntegerProperty but I don't understand how the private and public keys are supposed to be handled. I want to know where do I store the private key and once the notes have been encrypted and the user accesses them again how do I get the public and private key? Am I supposed to store they keys in the datastore as well?
The encryption is done at the server to encrypt the notes that the user saves. The notes are strings which are broken into characters and their ascii values are then encrypted. All of this is done at the server side once the user clicks "add note".
The decryption is done at the server side when the user logs in and his user id is used to fetch the notes he has stored which are decrypted to get the original ascii values and then form the original string.
Currently there is only one key pair which is generated in the code.
link to the application : http://cloudassignment-1102.appspot.com
Let me know if I need to add the source code as well.
Ideally you store the private key somewhere (very) safe. Since GAE is the platform of your choice you have a couple of options:
Put the key somewhere in your project where it is readable by the source code, but not publicly available (In Java this is usually a resources folder or WEB-INF, not sure what the equivalent for python is)
Use cloud storage and put your file there. It's a bit of overhead but if you ever want to change the key open-heart-surgery style...
Since a key is basically just an array of bytes you could define them as a constant byte array in your source. This would obviously be the least flexible choice.
EDIT:
Let me just say that this is a stupid assignment. It makes no sense at all to use asymmetric encryption if you hide all the encryption on your server. Since your data is always decrypted before it is sent to the user this is basically the same as symmetric encryption or no encryption at all.
But in the spirit of doing stupid things and learning while at it:
I assume your code generates the key pairs for each user. Therefore it is not possible to store the keys as constants in your code (GAE filesystem is readonly). Rather you can use any kind of database you wish (be it cloud datastore or cloud sql).
Since you should have a user database entity somewhere you can put the public key in there with the rest of the user information. You can serve the public key from the database through a cloud endpoint should you require it. Since it's not a secret you don't have to protect this endpoint.
The secret key could go in the same storage (datastore / cloud sql?) but i'd separate it so you cannot query for it and hand it out by accident. An additional table / entity with a reference to a user should suffice.
I need to store dynamic (will change every day/hour) value in django app.
Value will be generated every day, and I will need access to this key:value from all views in the application.
I don't want to store it in some model object instance, it should work like settings.py but I need to store it in database instead.
Any ideas?
what about leveldb? https://code.google.com/p/leveldb/
LevelDB is a fast key-value storage library written at Google that provides an ordered mapping from string keys to string values.
there is also python wrap https://code.google.com/p/py-leveldb/
or if you need distributed access checkout http://memcached.org/
Why not use a key-value datastore like Redis? You can use it as a cache backend or as a normal store, it's fast and will persist your data. https://django-redis.readthedocs.org/en/latest/ https://pypi.python.org/pypi/redis/2.10.1
I've been asked to encrypt various db fields within the db.
Problem is that these fields need be decrypted after being read.
I'm using Django and SQL Server 2005.
Any good ideas?
See: Using Symmetric Encryption in a SQL Server 2005 Database
Yeah. Tell whoever told you to get real. Makes no / little sense. If it is about the stored values - enterprise edition 2008 can store encrypted DB files.
Otherwise, if you really need to (with all disadvantages) just encrypt them and store them as byte fields.
I had the same problem, and created the following solution: http://djangosnippets.org/snippets/2489/
I happened to use M2Crypto as the cipher engine, but that can be swapped out if desired.
As TomTom notes, doing this just raises the bar for an attacker rather than making hostile decryption impossible - in addition to accessing your database, they now also need to access wherever you store the passphrase that feeds into the key derivation function. However, by splitting the key from the data it is protecting in this way, you at least now have the option to further secure that key (e.g. with a key management server) to raise the bar yet higher. Defence in depth is a good strategy, but you also need to decide what constitutues overkill for a given application.
It's also a terrible idea to encrypt any field that might be useful for searching or sorting purposes (I only use this trick to store OAuth credentials for a web service that doesn't support proper tokenised OAuth connections).
If you are storing things like passwords, you can do this:
store users' passwords as their SHA256 hashes
get the user's password
hash it
List item
check it against the stored password
You can create a SHA-256 hash in Python by using the hashlib module.
Hope this helps
Is there a simpler way to use uniqueness validation with Django Forms in AppEngine?
I understand that performance would be problem if we keep an uniqueness constraint but since the amount of data being added is very small performance is not a big concern, rather development time is a concern here.
Any help is appreciated.
You can use keys for uniqueness:
The complete key of an entity,
including the path, the kind and the
name or numeric ID, is unique and
specific to that entity. The complete
key is assigned when the entity is
created in the datastore, and none of
its parts can change...
Every entity has an identifier. An
application can assign its own
identifier for use in the key by
giving the instance constructor a
key_name argument (a str value):
s = Story(key_name="xzy123")
...Once the entity has been created, its
ID or name cannot be changed.
EDIT
As jbochi noted, this could be dangerous and you could loss data. Another way to achieve the same is using an hash function with shard counters. A good example is showed in "Paging through large datasets" article.
I'm working on an application that lets registered users create or upload content, and allows anonymous users to view that content and browse registered users' pages to find that content - this is very similar to how a site like Flickr, for example, allows people to browse its users' pages.
To do this, I need a way to identify the user in the anonymous HTTP GET request. A user should be able to type http://myapplication.com/browse/<userid>/<contentid> and get to the right page - should be unique, but mustn't be something like the user's email address, for privacy reasons.
Through Google App Engine, I can get the email address associated with the user, but like I said, I don't want to use that. I can have users of my application pick a unique user name when they register, but I would like to make that optional if at all possible, so that the registration process is as short as possible.
Another option is to generate some random cookie (a GUID?) during the registration process, and use that, I don't see an obvious way of guaranteeing uniqueness of such a cookie without a trip to the database.
Is there a way, given an App Engine user object, of getting a unique identifier for that object that can be used in this way?
I'm looking for a Python solution - I forgot that GAE also supports Java now. Still, I expect the techniques to be similar, regardless of the language.
Your timing is impeccable: Just yesterday, a new release of the SDK came out, with support for unique, permanent user IDs. They meet all the criteria you specified.
I think you should distinguish between two types of users:
1) users that have logged in via Google Accounts or that have already registered on your site with a non-google e-mail address
2) users that opened your site for the first time and are not logged in in any way
For the second case, I can see no other way than to generate some random string (e.g. via uuid.uuid4() or from this user's session cookie key), as an anonymous user does not carry any unique information with himself.
For users that are logged in, however, you already have a unique identifier -- their e-mail address. I agree with your privacy concerns -- you shouldn't use it as an identifier. Instead, how about generating a string that seems random, but is in fact generated from the e-mail address? Hashing functions are perfect for this purpose. Example:
>>> import hashlib
>>> email = 'user#host.com'
>>> salt = 'SomeLongStringThatWillBeAppendedToEachEmail'
>>> key = hashlib.sha1('%s$%s' % (email, salt)).hexdigest()
>>> print key
f6cd3459f9a39c97635c652884b3e328f05be0f7
As hashlib.sha1 is not a random function, but for given data returns always the same result, but it is proven to be practically irreversible, you can safely present the hashed key on the website without compromising user's e-mail address. Also, you can safely assume that no two hashes of distinct e-mails will be the same (they can be, but probability of it happening is very, very small). For more information on hashing functions, consult the Wikipedia entry.
Do you mean session cookies?
Try http://code.google.com/p/gaeutilities/
What DzinX said. The only way to create an opaque key that can be authenticated without a database roundtrip is using encryption or a cryptographic hash.
Give the user a random number and hash it or encrypt it with a private key. You still run the (tiny) risk of collisions, but you can avoid this by touching the database on key creation, changing the random number in case of a collision. Make sure the random number is cryptographic, and add a long server-side random number to prevent chosen plaintext attacks.
You'll end up with a token like the Google Docs key, basically a signature proving the user is authenticated, which can be verified without touching the database.
However, given the pricing of GAE and the speed of bigtable, you're probably better off using a session ID if you really can't use Google's own authentication.