Storing a password safely on the machine in this scenario? - c#

I am trying to find a way for my application to store a username and password (which must be retrieved later in raw form after decrypting - hashing is not an option). At first glance, I thought of some simple encryption algorithm.
However, most encryption algorithms (even the ones using a SALT or PEPPER) are flawed in that decompiling the C# executable can easily tell what the SALT and PEPPER is, and how the codes are decrypted. This can be fixed by obfuscating the code - however, ultimately even that can be broken.
I realize I might be going into extremes here. However, my application will be used by major companies around the world, and security is super important (oh, and I am also hypothetically interested in a solution).
The program will only run on Windows 7 or later.
Initially I looked into the ProtectedData class in C#, which makes the password secure for the current user. However, I want security for the current program as well (if possible), so that other programs running on the same user can't fetch the password.
Then finally, I realized that Windows 7 and later has a Credentials Manager in the control panel, and that applications can interact with this (and so can C#).
However, is the Credentials Manager secured to the current user, and the current program as well? Can other programs on the same user still access the credentials?
If yes, does there even exist a way of securing this data entirely? I trust in Windows 7's Credential Manager to be safe enough, but I am just concerned that other applications can freely take my application's data.
Edit - it should probably be mentioned that I have a code signing certificate from StartSSL if that's of any use. Not sure how that would help though, but maybe you have a clue.

From whom are you trying to protect the password?
The fact is, if the password is stored on the local computer, then someone who has physical access to that computer can access it. This is a fundamental limitation of security, computer or otherwise.
If it is a password that is fine for the user of your program to access, then Windows Credential Manager is in fact the best solution. If you want the password inaccessible to the average other piece of software, then you can encrypt it. But note that since you are decrypting locally, it will always be possible given sufficient effort to reverse engineer that decryption, regardless of the means of securing it (i.e. whether you use Windows CM or not).
If you don't want even the user to be able to get at the password, then it's simply not possible to safety store the password on the local machine. You'd have to come up with some other means of access, such as having a server you control that applies the password as needed to the resource on behalf of the user. Of course, then you have the problem of authenticating the user; if someone discovers their password, then they wind up with that user's level of access to whatever resource you're trying to protect.
The bottom line: use the available tools, preferably built-in OS features. Don't put more effort into security than is justified by the value of the asset, and try really hard to reuse "official" security mechanisms rather than trying to reinvent your own.

Related

How to store SNMP-V3 credentials in a C# application

i am creating a C# application (with .NET framework 4.6.1), which needs to communicate with an SNMP agent over SNMP-V3.
I found myself baffling with the question of how should i store the SNMP credentials.
i obviously cant hash them, because they are needed as plaintext when i'm initializing the SNMP manager, and i also don't want to force the user to enter them every time the application starts, because that could happen a few times per day.
The application is to be deployed on several computers, on a closed network, so i can't access to any cloud services.
I have come up with some techniques i can do this, and can't figure out which is the best for my use case:
prompt the user for the credentials at the installation, or at the first launch of the app, encrypt it using Microsoft's DPAPI, and decrypt it whenever needed for SNMP communications
Same as 1, but encrypt is using the user password (i have a login, and the login password is obviously hashed and salted).
I have found this project on github, which uses the Windows credentials manager- is this a valid option?
To me 2 seems like the most robust way, but i then go into several problems, because i can have many users in the system and i would have to do this for every user, and i am not sure it has any advantages in a security point of view.
The scenario i am supposed to face is one where i have an attacker inside the closed network, but if he has control over the machine running my app, it's game over right?
and if that is the case, why even bother with securing the passwords at all?
Any tips and enlightenment will be highly appreciated.
Thanks.
The only difference I see between 1 and 2 is that 2 assumes 1 encrypts the data unsafely (that is a false assumption, DPAPI encryption is good) and relies on the user password (which we do not know if it is safe). That is why I would discard option 2.
Now into the big difference, that would be DPAPI (options 1/2) vs. Credential Manager (option 3) and looking at this security stackexchange post How secure is the Windows Credential Manager? I would choose DPAPI.
So my suggestion would be, go option 1. My reasoning would be:
Credential Manager seems to be less safe than DPAPI
Relying on the user password strength is problematic because you do not know if it is strong or not.
A minor drawback on Credential Manager (if you finally choose option 3 instead option 1) would be it stores the data in the user profile directory, and accidents happen and it could be deleted by accident.

Storing credentials in an encrypted file

I'm working on a couple of projects that need to store user credentials for third-party applications, such as Paypal, Facebook developer creds etc. I've read a few books about different kinds of coding, including ASP.NET, WPF, jQuery, and all have nice examples on how to access the preceding services with own secrets, and also all of them use the exact phrase "in a real project you would store these in an encrypted file". None, however, give an example how to do so.
I have little (read: none) experience in encryption, but based on my understanding, I would need to encrypt a username and a password using some sort of key (salt?) and save them in a file. I would also want to be able to use these credentials on my apps so I would need to store the key (salt?) in my code.
Now my question is: How is it safer to store the decryption key, which is still plain text, in the program code, than the actual credentials?
Wouldn't the malicious user be able to decrypt my password-file as soon as he gets the key?
--EDIT--
I really mean my own credentials I need to store to log in to third party applications, not credentials of my users. For example I need to identify my self and/or my app to Google, so that users can log in to my app using their own Google account.
--EDIT 2--
To clarify, this is what I'm talking about. This screenshot is from asp.net PayPal tutorial:
Any quick pointers on good practises here?
You misunderstood the part about storing encrypted password* + salt: this is done when your system needs to validate someone else's credentials. In this situation storing password hash and the salt is more secure than storing the credentials, encrypted or not, because an attacker would have no way of getting the password back, even if he manages to get his hands on both the hash and the salt.
Storing decryption key in plain text is never a good option, because an attacker would get your users' passwords as soon as he gets access to the key.
There is no good solution to persisting your own credentials, encrypted or not. Your component that talks to 3-rd party services should use developer APIs from these providers. For example, PayPal provides two sets of APIs which you can use to access your account without having to store your password.
If you need to store a small amount of secret information in an encrypted form, use registry APIs to store the data in a key known to your application, and accessible from the user running your server-side component. This secret would be safe, as long as hackers do not hack the password for the account under which your service is running.
* Technically, password is not encrypted, it's hashed, i.e. there is no reliable way to turn the result of conversion back to the original value.
Your suspicions are correct. If the user has access to the key they can just go and decrypt the username and passwords themselves.
The two options you have are
Make it difficult enough to get the password that the reword of getting the password is not worth the effort to find it. This approach is done via things like Code Obfuscateors, I would not recommend this to someone starting out. Its not easy to get it right and it only takes one person who things it is "worth the effort" for it to break.
Don't give the user the information ever. Instead of storing the usernames and passwords in the program have your program call out to a server you own, then that server is what makes the request using the credentials. This approach is the more reliable one and is "unbreakable" (as long as your server is secure) but costs more because you now need to keep a server up and running that can handle the load of your entire userbase.

Store key file as embedded resource (how unsafe is it?)

If I have a stored key file used to decrypt the encrypted input coming into my application, and I store that key file as an embedded resource so that it is embedded in the assembly when deploying, how difficult would it be for someone to reverse engineer the application and retrieve the key file?
Also, the application is deployed through ClickOnce "Online only" mode which I imagine would also make it more difficult to reverse engineer? (I'm not exactly sure of the workings of ClickOnce but I wasn't able to find the dll's/assemblies on my local machine after running the application in online only mode...).
Update:
As Ralf essentially answered the main question below in his comment (answer: it's not really safe at all), here's some more information so that you knowledgeable people can possibly suggest a better security model.
The encryption will be used to encrypt the login password for my application, to be used in a SSO setup (the user will first sign on to a different system and then by clicking a link will be able to directly open my application without having to enter in their login details).
The encrypted data will be sent as a base-64 string URL parameter in the link that will launch the my click-once application.
I will also be developing the application that will create the encrypted data for the URL parameter (clarification: not the first application the user will sign in to for the SSO, I will only be creating a small tool to convert the plain text password into an encrypted base64 string).
It's only an internal application so bullet proof security isn't essential and ease of deployment is more important, but it'd be nice to know what the best practices and different options that are available.
Whether in clear text or encrypted, you don't want to store the password. When you get a password, all you should do is pass it to your server app where you compare it against the salted hash of the password you have in the DB. Even if you don't think security is that important, you need to take care with the password because people frequently reuse passwords across different systems. I know they shouldn't but they do.
If you want to implement a single sign on (SSO), create a sign on token on the server side and pass it back to the client, either encrypted or signed (HMAC is a good choice for signing). This is an unforgeable token because you need to know the encryption key or shared secret for the HMAC and that data is only known on your servers. So you have your SSO and all data involving the SSO is managed on servers so there's no data leakage or chance of spoofing.
As long as the aplication can be launched, the files have to be somewhere on the computer. You just have to know where to look. The reverse-engineering may be ugly but it is always possible. The computer has to be able to understand what he is supposed to do so you only have to extraxt the information one is looking for. Therefore the security of your application should never depend on the difficulty of reverse-engineering! I believe that a secure application should be open-source anyways.
You propably need a diffent security model. The important thing here is that you know against what you want to protect the data. If you simply want that you know the data is sent by the server and not somebody else (man in the middle attack) you could use digital signatures instead.
If you do not want anybody to read any data sent between server and client you should use some sort of ssl implementation to create an encrypted channel. Then you only need to watch out that the public key of the server is not altered on the client. This may be done by an certificate of an official CA but unfortunately those are usualy not for free.

how to store database password

I am sure there're lots of discussions already, but how to store a password in an application? (I meant not a user password to be stored in a table in a database, but the password to build connection string)
I've seen suggestions like store it encrypted in a flat file such as xml file, then read it +decrypt it at run time. If this application runs on a server, this is a very good choice, but what if the application will be deployed to end-users' pc? i.e. the flat file will be copied to the user's pc. Is this still a good practice? (my instinct is 'NO')
I know the existence of SecurityString, but then I also read in one post that SecurityString can be easily broken into, too.
Is it a good idea to use Password Vault that comes with Windows 7? Is there any good example of utilizing it programmatically? I've seen an example in msdn, but firstly it is labeled with 'windows 8', secondly when I downloaded the files and opened the solution in visual studio 2012 EXPRESS, it failed to open.
Any suggestion is welcome...many thanks.
--update--
Let's say, the application will be running on a handful of PCs within a windows domain. (1) At start-up, the application will do a LDAP authentication (active directory). Only upon successful authentication, the application will carry on, and (2) behind the scene the app can connect to the database, take user input to query the db, and this is where the db passwd comes into the play to build the connection string (no this is not SQL SERVER database so I don't think the option of using windows authentication is viable, unless a commercial plug-in is used).
The db resides in the same domain, and has been set up to allow certain range of IP addresses, and is SSL enabled. In short, it is quite secure in this sense. The only bit that is not yet secure is how to store the db passwd for the application.
What caught my eye was the Mysql Workbench. It will save db connections, including the password - which is stored in a password vault. That is mysql's own implementation of a password vault, and I am very curious as to how it is done.
There is no way to give a password to your users and expect it to remain safe. Even if it is hidden in your compiled application and hashed with a one way hash, the determined will recover it.
Instead you should consider your security architecture.
If you are providing services which your application connects to then you should look at providing some sort of more robust authentication as part of your public API.
If the connection string is for connecting to another part of the distributed software, then you should make the password configurable by the end user and store it in a keyring or other encrypted storage.
-- Update --
It looks like this might be what you are looking for;
http://www.microsoft.com/indonesia/msdn/credmgmt.aspx
If the application is going to be deployed where you have no or little control over the system security, ie, external user pc, then it may be worth creating a user login. Authenticate the user against this login, and then from a relatively secure server use whatever credentials you need to provide data.
This does not guarantee security, but it will be easier to maintain if you need to change the password at some point in the future, or if an individual user is compromised.

how to secure my windows application in C# from piracy without using database?

I am developing a windows application for my client, in .NET Framework 3.5, using C#.
There is no need of any database in my application.
I want to secure my application by making a registration process at the time of installation, where the user will be asked to enter a registration key, which should be machine dependent, otherwise the user can copy the installation folder and distribute to others, which i don't want to happen.
Please suggest me, how to achieve this.
Thanks,
Bibhu
I believe you will need a registration service.
When the user registers (they'll need to be online), their registration 'code' is sent to your registration service along with their machine details / other identification (username?).
Your service verifies this & returns a key which can be decrypted by your app using their machine details / identification. Your service also marks that registration code as 'used' so that no one else can get a valid key by using it.
The application stores the valid key in registry, or even config. It won't work on another machine because it is specific to the machine details.
my suggestion is this ways:
1)you can create a registery key after registration and in start up of your app check this registery key.
2)you can create a web service (over local network or internet) and on startup check if this version is registerd or not
3)create a custom file and store a hashed value based on machine and in startup of you app check this file
in every 3 way do not forget OBFUSCATION
There is no way to guarantee software is secure. Even registering over a network can be faked with the use of packet analyzers. In securing software, all you can do is make it slightly inconvenient for professionals, difficult for dabblers, and impossible for people with no knowledge. Generally, it's accepted that obfuscation is not a good protection, because someone will eventually figure it out and publish it anyway.
Also keep in mind that the more secure you make your program, the less usable legitimate users are likely to find it. It's a hard balance to strike between usability, security, and the value of what you lose if security is broken. There is no hard and fast 'right' way to secure something.
For machine dependent information, you can gather information about the hardware on that system, hash it somehow, and store the value somewhere, and then check it at the launch of the program each time. It's not fool-proof, but it allows some security fairly easily.

Categories