we have an application, where any registered user can create his own company and grant access for this company to any registered user.
Each company is represented by Postgresql's schema.
Is there a way to en/decrypt users data in schemas without using static key for en/decrypt stored in applications source code? Every user, who was added to company has to have access to company's data.
Thanks for answer
This is a question on which books could be written. So keep in mind it is a hard problem and you have to take a very complex, long-term approach to these problems. In essence, no you need a static key, and you don't want to store that unencrypted. You have several important questions you have to look at:
Key management and rotation. You will probably need the static key to be encrypted per user with public key encryption, and make sure they don't leave their private keys around unprotected!
Accidental key disclosure. So the data on the Pg side is now encrypted. How might someone get the key? In short you can't log queries routinely, you may want to set the error level to FATAL in the log, etc. PostgreSQL doesn't make this easy to prevent.
Accidental plaintext disclosure. This can happen through, say, creating an index of the decrypted data for performance reasons..... Also connection eavesdropping and much more needs to be looked at.
Related
I am building an iOS app for someone. The app will be used to take mock exams on for a professional license. The question data is stored in Core Data but the question and answers strings need to be encrypted as the client spent a lot of time writing them and doesn't want someone else stealing his work to use in a competing product.
So what I want to do is set the attributes in core data to transformable, use a custom NSValueTransformer to transform the strings to NSData and while they are being transformed use RNEncrypt to encrypt and decrypt.
So far so good.
Here is my predicament: I need to use a key to encrypt and decrypt the data but how do I get/create it?
My options:
hardcode it == bad!
generate key and store in keychain == not the right type of security. i.e.. does not protect against owner of the device.
generate key from user password == no other reason for the user to have to login.
the app connects to a server and gets a key with some authentication stuff(I don't know what is involved exactly) == I don't want to rely on a network connection for the app to work.
obfuscation, I feel like if I create a string from bits of other strings and method sigs and then hash it then that will be enough == It probably won't be.
My questions then are these:
- Obfuscation, can it be enough, has anyone else had success with it?
- From my research I've learnt that a hacker with an ipa can see all the hardcoded strings, class names and method sigs but they can't see the code inside the methods (is that correct?), so how could someone read the key if it was built up/generated inside a method?
- As the title, Can I use Obfuscation?
- Are there any options I have missed?
For the record, if I have to then I'll make people register and login.
You cannot store data locally securely. As soon as you are able to decrypt it an attacker can as well. That goes for EVERY encryption technique. No matter what you try.
You have to store the data or a different decryption key for each data point on a server and retrieve it one by one every time. You additionally have to make sure that the user does not just send 100s of requests and retrieves all data by hand.
Note that storing just one key on a server will result in the exact same thing as writing it hardcoded in the app. And not limiting the requests will just cause the attacker to need a little more time than just looking at an already decrypted local db.
Of course you can obfuscate it to make it seem like it has some good encryption behind it - but if someone WANTS to get the data, he will be able to.
Regarding the code in an ipa: you will not be able to see the original code but you will be able to see some code that produces the same output as the original code. As long as the device can produce the valid key, an attacker can as well.
I do not know if there is a huge community out there that is looking through random apps to steal some of its internal questions / answers / data, I doubt it.
You just have to make the product sooooo good that no competing product with the same data has any chance against it. The data itself can always be "stolen".
Currently I am creating a RESTful API for a mobile application. The RESTful API has a number of end points that allow users to exchange personal information between each other. I was testing how secure these endpoints were and quickly realized that if a third party managed to gain access to the API they could easily look up other user's information by guessing their user id or using an automated script to collect a wide range of personal information. This was due to the fact that I was using a primary key that was a simple auto-incremented integer which made it predictable and easy to determine other user's ids. I immediately began looking for something that didn't follow a distinct pattern. I came across UUIDs and decided to implement them with my existing rails app.
Was this a wise decision? I definitely see the upside to using UUIDs but upon further research I found that there were a number of negatives to this approach. Many sources claim that using UUIDs will cause performance issues with large tables. Are UUIDs right for my situation?
My second question is about implementing this in an existing Ruby on Rails application. I made the switch to UUIDs by following this article: http://rny.io/rails/postgresql/2013/07/27/use-uuids-in-rails-4-with-postgresql.html. I ran into an issue with enabling the uuid-ossp extension. I created a migration and put enable_extension 'uuid-ossp' inside the change function. I then changed the existing migrations to support UUIDs as their primary key and ran rake db:drop db:create db:migrate to recreate the database with the edited migrations. This failed with the error PG::UndefinedFunction: ERROR: function uuid_generate_v4() does not exist. I quickly realized that this was because I had created the migration that enabled the uuid-ossp extension after the migrations that I had edited to use UUIDs. When I changed the time stamp in the name of the migration to a date that preceded all migrations the db:migrate command completed with no errors. This felt very hack and defeated the purpose of having migrations. What is the correct way of adding this extension via a migration?
Edit in response to comments:
So a number of comments were made that suggested that I should just be properly authenticating users and checking their permissions before allowing them to view certain data. I have user authentication built into my application but will better explain my situation and why I needed something more than auto-incremented primary keys.
I have a number of users on this application and each user has the ability to create private and public contacts. Public contacts are viewable by everyone using the mobile application. Private contacts can only be viewed by the user who created them. However, a user can share their private contacts with other users by showing other users with the mobile application a QR code that has the contacts ID encoded into it. When the user decodes the contact ID a request is sent to the backend to notify the backend that the user is now an owner of that private contact. This allows the second user to now receive updates from that private contact. This is a large feature of my application. The aim here is to force people to have to exchange these contacts in person and to disallow others from seeing these contacts unless this process has happened.
Implementing this concept proved to be fairly tricky as all users could potentially share all private contacts with any other user on the system. I found this extremely hard to implement using permissions as which contacts a user can view is constantly changing.
Originally I implemented this with auto-incremented integers as my primary key for the contact IDs. It worked but forced me to create a very insecure API endpoint that essentially would take a user ID and a private contact ID as parameters and would add that user as an owner of that contact. Because auto-incremented IDs are so predictable a user with access to the API could essentially loop through a sequence of numbers calling the endpoint each time, pass the sequence number in as the contact ID and add themselves as owners to contacts that hadn't been shared with them. This would by pass the whole process of having to share the contact in person and in large defeats the purpose of having my mobile application.
I decided I needed something less predictable, completely random and unique to each private contact. I found UUIDs while doing research to solve this problem and changed the contact ID in my model to be of type UUID. Are UUIDs the best way to solve this? Should I use something else? Have I gone about solving this problem the wrong way?
Are UUIDs the best way to solve this?
You could use them as a solution. If you do, you should build a new contacts table and model instead of trying to migrate the old model. As well as being tricky to implement, any migration would immediately make existing contact/invite emails invalid (since they contain the old id). Briefly support both models, and retire the old auto-incrementing id model once you are happy that traffic using it is no longer important to your application.
There is still a flaw - your contact share links will now be long-lasting, and if anyone gets access to a contact's id for any reason, and know enough to construct the URL for gaining that user as a contact, then they gain the ability to share it to themselves and anyone else completely outside of the control of your application. This because you are relying on knowledge of the id as the only thing preventing access to the contact details.
Should I use something else?
In my opinion, yes. Use a separate nonce or one-off code model (with UUIDs, or an indexed column containing a long random string - you could use SecureRandom for this) that can grant rights to complete the sharing. When someone wants to share a contact, create the nonce object with details about what is being shared - e.g. the contact_id - and use it to generate email link pointing to a route that will find the nonce and allow access to the resource.
The model doesn't need to be called "Nonce" or contain that as a column, this is just a common name for the pattern. Instead you might call the new model "ContactShare" and the secret property "link_code".
This will allow you to resolve access to contacts using your app's permissions model as normal, and block the possible misuse of sharing links. When the controller with the nonce id or code is invoked, create permissions at that point in order to grant access to the contacts. Then expire or delete the nonce, so it cannot be re-used. I prefer expiry, so you can track usage - this can be as simple as a used boolean column that you update once the sharing request has succeeded.
Note I am not referring to Rack::Auth::Digest nonce routine, which is specific to server authentication. I did not find a RoR pre-built nonce model, but it is possible it goes under a different name.
I'm building a web-based app centered around security, privacy, and anonymity. One of the key principals of the app is that users can store sensitive data anonymously.
As a result, I expect to outsource system authentication entirely, preferably using OAuth or OpenID.
Is this even possible? I'd like to avoid storing email addresses or any other kind of user-identifying information on my side.
A friend of mine was working on this a few years ago. His idea was to hash an email address and a thumb or fingerprint into a unique image (biometric data is just a stream of bits, and in theory a fairly unique one compared to a human-input password like "123456").
That image could then be stored on that person's devices using their own password or bitlocker, or even printed out and locked away physically. The image would be the key when shown to a webcam or uploaded, sort of a reversal of QR codes.
Of course, the image-creation would be the potential tracking point. But if that was done entirely in memory or with a free and widely-distributed key generation tool then you would probably have some legal-protection from being compelled to reveal original users' data or identities.
(this all glosses over the need for wide use of biometric scanners and secure connections all around)
Edit:
Biometric data streams are slightly different each time they're taken. There is no "password recovery" if you hash a stream like this as-is, it will likely never be the same. Most dimensionality-reduction would make it far less secure, and might still leave a chance that it couldn't be reproduced.
To begin with, OAuth is a completely different thing, separate from your project's scope.
I guess it depends on your definition of "anonymous". If you use OpenID, you would be saving your users' OpenID URLs. In other words, your system would be precisely as anonymous as your users' OpenIDs.
A more intrinsically anonymous solution might be to simply let your users enter an arbitrary string to identify themselves. Returning users would simply type in that same string again. If you want to display a user's "identity", you could run that string through a hash function. No registration required (and not unlike 4chan's secure tripcodes).
I'm working on an app that has a red button. What that means is that every client account has two (secret) keys that are automatically generated. When someone enters those keys on a special (public) page, a certain process will be set in motion. The process is not critical, but
That's all taken care of, the keys are automatically generated on user account creation, stored encryped in the database and are shown to the user once so he can distribute the keys as he sees fit. He can of course reset the keys if he wants to.
The thing is, some clients keep forgetting the keys. Our solution is to reset the keys and redistribute the new keys, but for some clients that's just not practical. I'd like to offer the option of retrieving the keys without resetting them.
My idea was to be able to decrypt the keys using the user's password, meaning that the already logged in user would have to enter his password again, which was used to encrypt the keys and is now used to decrypt them. I'm just not sure how that would technically work (is there an encryption/decryption algorithm that I could use?) and whether there's anything I should consider before employing such a technique.
Does anyone have any ideas on this? Maybe even a better suggestion?
You want to check out ciphers like AES.
I'd check out this gisthub example on how to use Ruby and AES for encryption and decryption.
I am creating a rails application that needs to store a large amount of sensitive data. To assure my customers that the data is being protected, I want to encrypt it on a per-user basis. I have done research looking for gems that can accomplish this. So far I've found strongbox and safe. Together, this would seem to provide a solution for me.
However, I am wondering if this is a common practice. It would seem that most rails applications have some sensitive data to store regarding their users. AuthLogic is handling my password encryption, but emails and other personal data are just as sensitive. Is it common practice to leave these items unencrypted in the database and assume that it will never be compromised? I understand that the database resides in an area that can not communicate with the outside world, but a determined attacker could easily compromise this. Is it common practice for Rails developers leave their data unencrypted and simply trust the security of their web server?
The problem with encrypting your database is that anything you encrypt cannot be used in a SQL query, and also, it still has to be decrypted before it can be used. This means that you need to place the decryption key in close proximity to the database, and in most cases, if someone can compromise your database, that means they have also compromised your decryption key at the same time. Thus the encryption step has bought you very little. With passwords, no decryption is necessary because it's actually a hash function. You're far better off making sure the database is never compromised in the first place.
Always assume that if a hacker can compromise any portion of your security, they can compromise all of it. Chain is only as strong as its weakest link and all that.
Credit card numbers and social security numbers (which fortunately you don't usually need to index on) are probably the most obvious exception to this, but if you have to ask this question, you've got no business storing those items in the first place. There's all kinds of legal trouble you can get into for messing that stuff up.
Credit card number, SSNs, etc should always be stored encrypted.
Passwords should always be stored encrypted, using a one-way hash. This means that when the user supplies a password, you can determine if it matches what you stored in the DB, but given only the encrypted representation in the DB, you cannot from that determine their password, short of brute force/dictionary attacks.
I find that in my app's, I like to add unencrypted_**** readers and writers to my class, to make dealing with the encrypted representation painless.
class User
# has db column encrypted_cc_number
def unencrypted_cc_number
WhateverEncryptionClassYouUse.decrypt(encrypted_cc_number)
end
def unencrypted_cc_number=(val)
self.encrypted_cc_number = WhateverEncryptionClassYouUse.encrypt(val)
end
end
Using layered security mechanisms and strong cryptography is good practice if you are storing a large amount of sensitive data. It is required by the Payment Card Industry’s Data Security Standard (PCI DSS). I suggest that you read the following guideline document: https://www.pcisecuritystandards.org/pdfs/pci_fs_data_storage.pdf.
You should definitely not "assume that it will never be compromised"