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.
Related
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.
I'm building an application that syncs data between users' Exchange Server accounts (version 2007-2013 supported) and the application.
The application can't use impersonation (at least not in the typical case) as users could be on any number of domains and exchange servers.
I know I'm going to have to ask for their username/email-address and password initially. However, I really don't want to be responsible for storing these credentials if I don't have to (even if they are encrypted, I'd rather not).
I'm not sure what questions to ask, so I'm going with these:
How does Exchange Server authenticate? Do the user's credentials get sent directly to the server as they are, or are the hashed together before being sent across the wire? If they are hashed, how can I get/generate this hash for re-use on successive authentications?
Does Exchange Server send some sort of authentication token that can be re-used later (and forever, until password change or invalidation)?
If you know of a solution to the problem, that the answers to these questions won't address, please do provide it instead.
Active directory federation services is exactly for such tasks. You can read about it there.
As mentioned by Kirill, ADFS 2.0 is one of the best solution for your task. You can also look into other SSO implementations as well. Though the main goal of SSO implementation is to maintain single Login state for multiple application (thereby reducing multiple Login prompt for each application), some of your application goals seems relevant. Please do a thorough research on all the tradeoffs before heading to the sso implementation since there is a small degree of complexity involved during implementation. SSO suits best if you are considering integration of multiple application in the future with the exchange server.
To answer some of your questions (in the same order - considering an SSO scenario with ADFS 2.0):
The authentication to exchange server will be done via ADFS 2.0 (Which provides security tokens (STS service) - to your application after authenticating with AD/ main Directory service). All the communication is encrypted and token signing certificates are used for Integrity and confidentiality.
The lifetime of Security tokens sent by ADFS 2.0 can be configured and reused as required. Please see this blog post for more details.
Also you can configure the ADFS 2.0 (Federation Service) to send only the relevant claim values (like username and email address) to the application, thereby improving the data security.
The System.Net.CredentialCache should work to suite your needs. The WebCredentials is a wrapper for the System.Net.NetworkCredential. Depending on the connection type/domain ect you should be able to utilize System.Net.CredentialCache.DefaultNetworkCredentials or System.Net.CredentialCache.DefaultCredentials
perhaps you should take a look at this Links Connecting to EWS by using the EWS Managed API , Connect to Exchange - Getting Started Tutorial? hopfully it will give you a new idea how to solve your problem :)
because if i understand the information correctly you maybe over think problem but i haven't any experiences so i could also absolute wrong
Bottom Line
If you can't configure anything on the server, there's no automatically generated token to use. It's unfortunate, but you're facing the same general problem that web browsers have--saving the password.
It's worth noting that any authentication needs to be over SSL (an https connection) to prevent a third party listening in on the authentication.
Password storage thoughts:
My suggestion is then to be somewhat creative when storing the password. You can use a keyed encryption algorithm, and then use a hash to generate the key, letting you arbitrarily choose what goes into the key. You would want at least 3 pieces of information going into this: something unique to the device, something unique to the app, and something unique to the exchange server.
For example:
a unique id given by the device (it doesn't matter whether or not this value is app-specific or not, merely that it is consistent)
a (long) string of information compiled into the app, possibly keyed to installation specific values, say the time when the app was first used
something unique to the destination, like the DNS name and perhaps some more specific server info
If you're willing to provide the option to the user, you could have an authorization PIN of some kind that would also be added to the data.
All this data gets put together in one byte array and hashed. The hash (or part of it, or it twice, depending on the hash size vs. the key length) is then used as the key for the encryption of the password.
You could also include some check information along with the password to be able to check client side whether or not the password was decrypted correctly. (If the wrong data is hashed, the wrong key is generated, and the wrong result comes from the decryption).
It's worth noting that all the information to be used for putting into the hash needs to be stored on the device, which is why I would suggest a Pin to authorize the usage of the account.
I have developed application which supports trial mode. But now I need let some users to get full via activation code. Scenario is user downloads trial application and he can enter activation code for the app and then user can use full features of the app.
Can anyone please suggest me a way to do this.
You need to think about how you will authenticate the code - I'm guessing that you don't want them to authenticate the code via the store so you will have to provide some backend service to do this.
The service will obviously require the activation code to be sent to it (you should store this in the remotesettings), and you might perhaps want a device unique ID sent to - you can use the unique id for this.
Your service should then validate how many times it has seen the code, and if it's happy it should hash the code, the device ID, and a secret shared with your application - this will need to be embedded inside your app code.
For additional privacy for the user I would advice hashing the device unique ID with the shared secret before sending it to the server.
You need to store the returned activation code inside your app - and there isn't a lot of choice - I would personally store this code in the LocalSettings area.
Now on startup you need to verify that the stored activation code is valid. If you have an internet connection then you can do this by asking the service if the code is valid, but you must make an arrangement for offline checking. This is simple enough as the activation code, plus the hashed device ID hashed against the shared secret should equal the stored activation code - depending on your type of application you might want to only allow 5 activations this way before requiring internet access (pick a high number as this could really annoy users)
Finally you need to consider users that have multiple devices - according to the store you can have 5 installs of the same application, for the same users, across different devices. To accommodate this we have stored the activation code in remotesettings, so on startup check if the code exists, and if it does automatically send the code and the device id to your service for activation.
The only other thing you need to consider is how on earth do you secure the shared secret in your application? Unfortunately there aren't many options for this. It really depends on how secure your app need to be. If you are totally paranoid then obfuscate your code, but this just buys time. If you need more than that then I suggest you send the device code, hashed with a cryptographically random nonce to your service, this will return back what you sent, but hashed with the secret. Unfortunately this will make offline validation of the activation token impossible, so you will have to build in a grace period where internet connection is not required.
Or you could use in app purchases.
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.
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.