How can I store a configuration property such that its value can't be read anytime with bees config:list? We use a master password as a System property (although we are open to other options there) that allows us to decrypt other passwords. However, we realized that any user with CB SDK access can easily list that value. What are our options here to store it encrypted or other ideas for a solution?
Unfortunately, no encryption option available yet, unless you were to bake it yourself in a ClickStack, for example.
Still, this would be an interesting feature, and I will talk about this possibility with my colleagues.
Related
I have a webapp that uses keys and credentials to call API endpoints from external services like payment gateways, database providers, and such.
I have these options in mind to keep these values:
Set environmental variables before app start and load them when the app runs. If required values are not available, e.g. not set, exit the app.
On app start, ask user (myself or an administrator) to enter the credentials. If required fields are empty, exit, otherwise continue loading the app.
Keep them in a config file as plain values. This is the least preferable way as to me.
Which of these should I use if I want to keep keys as safe and secure as possible?
I would go with user environment variables, as it is recommended by both google and amazon.
If you go for storing in plain text files, remember to not keep them in your app's source tree (if you use some version control, you may end up exposing them to public).
Also, remember to regenerate your keys periodically.
I think you should, as you said, use configuration files. And maybe encrypt it ?
If you have lots of keys to manage, environment variables get clumsy. A hybrid approach works for me: encrypt the secrets and put them all in config (typically as base64). Use the same encryption key for all of them, and pass it in as an environment variable.
So you only need to make one environment variable to secure as many other secrets as you need.
Let's say I have a program written in VB.Net with encryption code that relies on a key being set to encrypt and decrypt. How do I securely store the key in the program? If it's plain text in the code, it could be reverse engineered. If it's a setting, then it is stored as plain text in the x.exe.config file and even easier to find.
Can the x.exe.config file be set to encypt? If not, what's the safest way of hard coding the key into the program?
The method I've used is encrypted using a different method, then encode that (as it's non-ascii text) and store that in the settings, but that in turn could be decoded if the program is reverse engineered.
What do other people do in this situation?
You've set to an impossible task. The problem is that by hardcoding the key into the program, as you've noted, the user can still get the key by reverse engineering. If you put it in a file somewhere, the program needs to be able to read it, and therefore the user can also access it in the same way.
The fundamental problem you have is that the software needs to access the key, and for that, the key must be stored somewhere it's reachable by the user too. It can be within the binary or in the computer, but the binary can be analyzed and the file system can be inspected. Encrypting a file protects the key, but just recreates the problem with the new key.
This is also the very same problem that all DRM schemes face. They give users access to the the full software but want to limit it in some ways, but the user has everything in his computer to run the software. That's why it's always possible to pirate every desktop software, if enough effort is put towards it. You only can make it more difficult by obfuscating the key.
But what can you do then?
An alternative approach is to not have the user to have the DB credentials at all. Or make them useless for anything significant. I can think of two approaches here:
Have the system communicate with a webservice and never to the DB directly. This way, the user only knows the address of the server and the WS can request any authentication as needed, before going to the DB. The WS is then the only one to ever touch the DB. This is what all websites do in practice, the visitor doesn't ever sees the DB, but interacts with it though the web server.
Another option would be to give the user direct DB access, but those credentials only give permission to call some stored procedures (or access views without sensitive data) and those in turn request some sort of authentication before proceeding. This way the DB credential becomes not that sensitive as long as its permissions are kept to the bare minimum and privileged actions are properly validated before proceeding.
The Glassfish JDBC realm features several different properties you can set.
I am interested in the Digest Algorithm and Password Encryption Algorithm properties (that's how they show up in the admin console).
The second one is new as of Glassfish 3.1.2 as near as I can tell.
I have consulted the official Glassfish 3.1.1 documentation but it does not address the new property, and does not really explain what the first property is used for.
There is a documentation bug that references a bug number (13363269) that must point to a defunct bug system because I can't find the bug to which it refers. This phantom bug presumably details what the Password Encryption Algorithm property is for, but alas seems to be lost to the mists of time.
From the command line, the property is named (improbably): digestrealm-password-enc-algorithm. It looks like this will live on next to the digest-algorithm property.
I attempted to read the source code, but the JDBCRealm.java file appears to be missing although I am doubtlessly simply looking in the wrong place. A prior copy that I found does not reference the property anywhere.
What are these two properties for? I have a hazy sense that together they ensure that if I use the realm to login with a plaintext password I can somehow delegate the hashing-and-comparing operations to the realm, provided of course that the hashes used to store the original password and the hashes used on the incoming password were calculated the same way.
The manual also indicates that if I want to use digest authentication that I should be specifying the jdbcDigestRealm JAAS context. If I don't want to use digest authentication, then I should be specifying the jdbcRealm JAAS context. To my eyes, this looks like yet another place where I am effectively specifying what kinds of hashing algorithms are involved.
Thanks in advance for any pointers.
I wrote about this (related issue) here - Glassfish 3.1.2 JDBCRealm configuration.
In short, the password encryption field does not seem to be mandatory at all anymore - so just storing passwords as SHA 256 hashes should work well enough.
What algorithm should I use for encrypting and embedding a password for an application?
It obviously is not bullet proof, but it should be good enough to thwart someone scanning the database with a hex editor, or make it hard for someone who has the skills to use a debugger to trace the code to work out, either by scanning for the encrypted password, or using a debugger to run through the decryption code.
Object Pascal would be nice.
Major Edit
I think I did not explain myself well enough. The password needs to be decrypted back into its original form and applied. The application itself uses a local SQL database and a local webserver, and the password is fixed and can't be changed by the end users. It is to ensure that changes to be made only from within the app itself. The user passwords are only to allow access to the app itself, rather than the database
/vfclists
If you want an easy solution just stick with a good hashing algorithm like MD5 and store just the hash inside your application. Then whenever the user inserts the password you will calculate the hash of the password and check if it's equal to the one stored.
Of course this approach is a simple solution that doesn't allow you to retrieve the password if it's lost but it should work quite fine if you just need some protection..
EDIT: I mentioned MD5 that was fair good but not anymore, of course you can choose any other stronger function like SHA-2 (512/384) that is more robust. I just wanted to explain an approach more than using a specific hashing algorithm.
SHA should be ok for you, best with salt.
I don't know Object Pascal very well, but probably this will help you:
http://sourceforge.net/projects/op-crypt/
When an application has to do password checking only, it is best to save a hash. An hash can not be decrypted, but it can be checked whether the password the user enters has the same hash.
If you want to save the password so that it can be recovered, it is best to encrypt it first, using some crypto library.
I would suggest SHA1, its one way encryption, i've used it before and by far no one has decrypted it!
If you need more information on sha1 visit http://en.wikipedia.org/wiki/Secure_Hash_Algorithm and http://www.openssl.org/docs/crypto/sha.html.
PS: If you're using php you can simply encrypt with SHA1 using the sha1(); function!
I suspect that what you're aiming for is not storing passwords in the application, but trying to prevent the application itself from being run without the password, as a form of DRM. If that's the case, and you're looking to stymie people with debuggers, I think you're well into the realm of needing either a hardware dongle, or a network-based lock. Off the top of my head, I know SafeNet carry products that do this (and I've had some exposure to them in the past, they seem decent), but I don't know how well they compare to the rest of the market.
If you want as much real security as is possible in the scenario you're describing, you should require that when the system is installed an "administrator" enters the database password and his own administrator password; the application should then store a salted hash of the administrator's password, and it should store the database password encrypted with a differently-salted hash of the administrator's password. The database password (or information sufficient to reconstruct it) will be kept in memory while the program is running, but absent the administrator password there would be no way to retrieve when the program isn't running, even with full knowledge of the system.
If it's necessary to allow multiple users to access the database, an "add user" button could allow the addition of a user account. When the user types his password, use it to store hashed/encrypted data as with the administrator.
Any user with a debugger would be able to leverage his knowledge of a valid user account and password into knowledge of the database password, but someone who didn't have knowledge of a valid account password wouldn't be able to do anything.
If I am interpreting your question right, then you want to basically distribute your application to users, allow them to run it, and have the application update your database. At the same time, you want to prevent that person from being able to log in to the database and use it themselves directly.
If your program can be decompiled (like java, but I don't know about other languages like C, C++), then the person who has your application will be able to see the source code. Once they have that, there will most certainly be some way they can discover the user name and password. Even if your source code has stored the password using a reversible encryption algorithm, the person who holds your source code will be able to write similar code as yours to reverse the encryption and discover the password.
Even if your application cannot be decompiled, the user may be able to capture the network packets it sends to the database and determine the password from that. I don't know if you can communicate with the database over SSL.
Instead, I believe you need to split your application into client and server applications. You can write a restful web application, or use a messaging service (like JMS for example), and write a client application that uses it.
In that case, you may or may not want to have user accounts that are managed by your server side application. Let me be clear here, I am not talking about database accounts, but accounts that your application manages, and whose details happen to be stored in the database. If you do create user accounts, you can follow the pattern in my original answer shown below.
============== Hashing Approach, my original answer ============
As others have already mentioned, it's best to add salt to the password and use a digest algorithm before you store the password in your database. However, I think a little more detail is in order.
Using SHA1 or SHA2 with a salt value may be pretty strong, but there are even stronger methods. I highly recommend that you read this section of the spring security manual. I don't think you are using spring or java, but that section covers the concepts involved very well. Allow me to paraphrase:
Use at least an 8 byte salt value, up to 16 bytes would be great. The salt value should be different for every account, if it is the same then a cracker will only need to produce one rainbow table! It should be randomly generated. The documentation doesn't say this, but I also recommend using a secure random number generator, don't use a random number seed that produces a consistent sequence of numbers.
You should hash the password multiple times because it will cause brute force password hacking attempts to take increasingly more time. Indeed, you may want a slow password encoding algorithm instead of a fast one.
Store the raw salt value in the database along with the password, you can even store it in the same field/column. This is required so passwords can be verified in the future.
The BCryptPasswordEncoder is a good example of this.
===============
One alternative approach that may or may not solve your problem is to create a database account that has limited privileges. For example, you could create a database account that can only select, update, insert, and delete on specific tables in your database. You may not find this acceptable, because you may not want to let people do those operations directly, while you may want to let the application do those operations. It depends on your specific situation.
i am starting to use cryptostream class. i may be wrong, if you encrypt something, close the app, and then try to decrypt it, it will not be able to because a different key will be generated. because i do need this functionality, i am wondering if it's possible to save the key in application settings and whether this is the right way to go?
If you always run your app under the same user account (it can be a local user or a domain user), the best option would be to use DPAPI. The advantage of using DPAPI is that you do not have to worry about the key (the system generates it for you). If you run the app under different user identities, then it gets more complex because the options that are available range from bad to worse (the major problem is: how do you protect your secret: key, password, passphrase, etc). Depending on what you want to do, you may not need to use encryption at all (e.g. if you want to encrypt a connection string, consider using integrated windows authentication, which does not require a password). For more info on the topic, check out this MSDN article: Safeguard Database Connection Strings and Other Sensitive Settings in Your Code; it may give you some ideas.
Lots of applications save the keys in configuration files. It's a common bad practice.
It's not secure but all secure options are hard to implement. There are options using different factors,
You can derive the key from a password using PBE (password-based encryption). But you have to enter a password to start your application. This is so called "What you know" factor.
Put the key in a smartcard. This is very secure but you need to have access to the card on the machine. This is called "What you have".
Ignore other schemes involving encrypting keys with yet another key. It doesn't really change the security strength.