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
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'm making a company back-end that should include a password-safe type feature. Obviously the passwords needs to be plain text so the users can read them, or at least "reversible" to plain text somehow, so I can't use hashes.
Is there anything more secure I can do than just placing the passwords in plain-text into the database?
Note: These are (mostly) auto-generated passwords that is never re-used for anything except the purpose they are saved for, which is mostly FTP server credentials.
You can use MySQL's ENCODE(), DES_ENCRYPT() or AES_ENCRYPT() functions, and store the keys used to encrypt in a secure location.
Use encryption. The passwords won't be in plain text so you'll have some security but it can be reversed.
The code in this answer should do the trick.
I am writing a desktop application in Python. This application requires the user to input their GMail email and password (however an account must be created specifically for this app, so it's not their personal (read: important) GMail account). I was wondering what would be the best way to store those login credentials. I don't need it to be super secure, but would like something more than storing it as plain text.
Thank you in advance.
Any chance you could not store the information on disk at all? I think that's always the most secure approach, if you can manage it. Can you check the credentials and then discard that information?
You can always encrypt the information if that doesn't work, but the decryption mechanism and key would probably have to reside in your program, then. Still, it might meet your criterion of not super-secure but better than plain text.
Use the OS keyring for this, which is the job of the python-keyring module.
Use the platform's native configuration storage mechanism (registry, GConf, plist).
If you are using Qt for your app, you should really use QSettings and let the framework handle the storage for you. Note: QSettings will NOT encrypt anything for you, but will store values in the most appropriate location depending on the platform it's running on.
Regarding security, you really should use OAuth, like in the example here, and just store the resulting token.
This question is based on the answer.
I would like to know how you can hash your password by SHA1 and then remove the clear-text password in a MySQL database by Python.
How can you hash your password in a MySQL database by Python?
As the documentation says you should use hashlib library not the sha since python 2.5.
It is pretty easy to do make a hash.
hexhash = hashlib.sha512("some text").hexdigest()
This hex number will be easy to store in a database.
If you're storing passwords in a database, a recommended article to read is Jeff's You're Probably Storing Passwords Incorrectly. This article describes the use of salt and some of the things about storing passwords that are deceptively easy to get wrong.
http://docs.python.org/library/sha.html
The python documentation explains this a lot better than I can.
You don't remove the clear-text password when you hash the password. What you do is accept an input from the user, hash the input, and compare the hash of the input to the hash stored in the database. You should never store or send the plain-text password that the user has.
That said, you can use the sha library as scrager said (pre-Python 2.5) and the hashlib library as David Raznick said in newer versions of Python.
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.