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.
Related
Is there a way to connect to MySQL DB with maybe RSA keys or by providing SHA-256 encrypted login and password in code? Because let's say we want to post our app publicly. Anyone who can decompile the app will see all the code including our login and password to the database.
I was wondering (purely theoretically) because If I wanted to implement some kind of codes system (like those from gift cards or PaySafeCards) to my app so the user could have like a premium membership or different feature and I wanted to store them in my database then someone could just decompile the app, steal the login and password that were in code, access the database, steal the codes and have the membership for free so how would I prevent a situation like that from happening?
You need to use environment variables. Check this website to learn more. You will use the os module and more specifically os.environ which returns a dictionary that contains all current environment variables.
If you want to publish your code on a public platform such as Github you can set private environment variables. Check here
I am wondering what are the steps one would need to take should the production secret key become compromised. Luckily, that is not the case, but it would be good to know, nonetheless.
In particular, what happens if one simply swaps the old key to a newly generated one? Since it is used in making hashes, does it break the entire system or make it unstable?
In the case of a compromise, would the response be as simple as generating a new key and inserting it into the production settings?
The SECRET_KEY is used for the following:
All sessions if you are using any other session backend than django.contrib.sessions.backends.cache, or are using the default get_session_auth_hash().
All messages if you are using CookieStorage or FallbackStorage.
All PasswordResetView tokens.
Any usage of cryptographic signing, unless a different key is provided.
"If you rotate your secret key, all of the above will be invalidated. Secret keys are not used for passwords of users and key rotation will not affect them."
You can use the following function to generate a new key:
from django.core.management.utils import get_random_secret_key
print(get_random_secret_key())
Simply copy/paste the printed results into your settings.py.
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.
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
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.