5

I am creating a windows service that sends email to a user. It uses a Gmail account to send the email, so it needs a password to access the account. It also needs to do this automatically, without user interaction. How do I securely store the password so that the application can authenticate with Gmail?

So far the options I can think of are:

  1. Hard-code the password
  2. Save the password in plain text file with restricted permissions

Neither of which is very secure in a Windows environment.

7
  • 2
    I'd say we'd want some kind of risk assessment here before giving you some over-complicated highly secure result, I mean if we're afraid of someone decompiling and finding the hard coded password, we need to know what language it's in, and if it's .NET you're pretty much screwed being as full decompilation back to the CLR is easy and any encryption methods are painfully transparent. Dec 16, 2011 at 18:21
  • 1
    Yes, it's .NET, though I don't have to worry too much about decompiling. I'd just prefer a more secure approach than hard-coding if it's simple.
    – Phil
    Dec 16, 2011 at 18:25
  • Is this on a server, or on each individual desktop? Dec 16, 2011 at 18:27
  • Will probably be on a server, though there is a possibility of it being leaked somewhere else by my overzealous salesman coworker. "Hey we developed this app, here you can use it!" without asking for permission...
    – Phil
    Dec 16, 2011 at 18:30
  • What is the ultimate purpose of this gmail account? Are you proposing some sort of master account used entirely to send email, or are you assuming that all end-users will have their own gmail account? The former may run into problems with ISPs filtering outbound port 25, 465, 587, etc. Dec 16, 2011 at 19:28

4 Answers 4

6

I think google's SMTP server supports OAuth, so you don't really have to store the password. That requires (one-time) user interaction to set up, but you'd have to ask the user to register anyway, so when you do that you can also establish OAuth link to Google. See more in Google's help site.

4
  • Not really familiar with OAuth, what prevents me from using the token on another computer, or in my own software? If it's on a per computer basis, then this is the correct answer. Dec 16, 2011 at 19:04
  • Well, if you steal all OAuth keys then it doesn't matter really, whatever information you keep on the client side, if I create bit-by-bit copy of it I could use it the same way you do. However, OAuth does not send the keys out so it's more secure against stealing data in transit, replay attacks, etc.
    – StasM
    Dec 17, 2011 at 22:57
  • Oh, so in this case it provides more security in transit (which is always good, though I think Google enforces TLS, or at least supports it) but doesn't actually resolve the problem of hijacking the account when someone at the business hands over the system to someone else to use. Dec 19, 2011 at 14:35
  • 2
    @StrangeWill: OAuth does prevent hijacking the account. OAuth lets you use the account, but not change the account password. You can decide what permissions an oauth token gives. A user's gmail token won't give access to that user's webmaster account, but a user's Google password will. If necessary, a user can revoke the OAuth tokens. Note that this does nothing to answer your original question of how to store a token securely; it only tells you which token to store.
    – Brian
    Oct 2, 2012 at 21:20
5

You probably want to use DPAPI to store the password securely within Windows. That will let you keep the password encrypted, and Windows will manage the keys for you and it can be locked down to either the user or application. Of course, a user with administrator privileges can get to the key. For more info: http://msdn.microsoft.com/en-us/library/system.security.cryptography.protecteddata.aspx

You could also make it a little harder to find the location of the password with isolated storage: http://msdn.microsoft.com/en-us/library/3ak841sy(v=VS.100).aspx. With that being said, isolated storage is NOT a security mechanism.

1
  • 1
    AFAIK, DPAPI does not lock "down to either the user or application" unless you consider the use of optional entropy as locking a blob down to the application. The DataProtectionScope options are CurrentUser or LocalMachine. If additional entropy is used and that entropy is known only by the application, then you could consider the blob tied only to the application (until the application is reverse engineered).
    – mikeazo
    Jun 24, 2014 at 12:55
1

To secure the password, you need to secure access to the files. This means that only trusted users can have physical access to the server (it should be in a locked server room) or remote access (file shares, Remote Desktop, etc.).

If you are going to distribute the application, the password (and user name) should be stored in a configuration file so that other users can configure it to use their own user and password. (And they also need to secure their own server.)

0

I would say because it's .NET, and decompilation involves downloading ILSpy and spending about 30 seconds of reading your nearly raw source (including variable names)... I probably wouldn't even bother, being as anything outside of sending all requests to a server YOU own that will do the auth, anyone that isn't terminally lazy can decrypt the password no matter how much time you waste on heavy encryption on locally stored files.

I'd probably make it so that you can change the SMTP server, and make sure if the software gets redistributed that they hand out the one with the blank SMTP server settings, and basically write off the GMail account if they don't.


If you want to feel a tiny bit more secure, you can drop in something simple, like an AES key + the encrypted password, and use that as the config file, but that isn't going to stop any competent programmers, but at least you didn't spend days or weeks trying to develop something over-complicated that I can still crack in the same amount of time (being as I just have to add your .exe as a resource, execute the call to pull your config, and read the raw variables in memory).

Though you might as well just base64 it so it isn't raw (because this is stupid-easy), because as I said, anything you do is fairly easy to crack.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .