views:

650

answers:

4

I'm Looking at using Amazon S3 and simpleDB in a desktop application.

The main issue I have is that I either need to store my aws credentials in the application or use some other scheme.

I'm guessing that storing them in the application is out of the question as they would be easily picked out.

Another option is to create a web service that creates the aws authentication signature but this has its own issues. Does the signature require all the data from a file thats being uploaded? If so I would have to transfer all the data twice. There would then be a central failure point which was one of the main reasons for using aws.

Any ideas?

UPDATE:

I needed to make it a bit clearer that I'm wanting to store my aws credentials in an application handed out to others. DPAPI or any other encryption would be only stop people simply using reflector to get the credentials. Using any encryption still needs the key that is easy to get.

A: 

The main issue I have is that I either need to store my aws credentials in the application or use some other scheme.

Does Windows have a system-wide service similar to Apple's Keychain Manager? If so, put your credentials there. If not, perhaps you can build a watered-down version of it for storing a strongly-encrypted version of your AWS credentials.

Does the signature require all the data from a file thats being uploaded?

The HMAC SHA-1 signature is an encoded encryption of the HTTP request headers. This signature is a hash value and will be very short relative to your data, only 20 bytes long.

Alex Reynolds
My point about the signature was that if I was sending a file, would I need to send it all to the web service just to generate the signature?
Tim
No, you generate the signature on your end. They generate their own signature on their end, and they then compare their signature with yours. If the two signatures don't match, then the request fails. The signatures have to match in order to authenticate and authorize your request.
Alex Reynolds
A: 

You can encrypt the config file and/or use ProtectedData. Here's my blog post on both.

UPDATE: You might be a be to encrypt your app.config as part of an install step. Sample here: http://www.codeproject.com/KB/security/encryptstrings.aspx. Not great, but the best I've found so far.

Jon Galloway
DPAPI is only useful for protecting the users data, I need to store my own personal credentials!
Tim
+5  A: 

Tim, you're indeed hitting on the two key approaches:

  1. NOT GOOD ENOUGH: store the secret key "secretly" in the app. There is indeed a grave risk of someone just picking it out of the app code. Some mitigations might be to (a) use the DPAPI to store the key outside the app binary, or (b) obtain the key over the wire from your web service each time you need it (over SSL), but never store it locally. No mitigation can really slow down a competent attacker with a debugger, as the cleartext key must end up in the app's RAM.

  2. BETTER: Push the content that needs to be protected to your web service and sign it there. The good news is that only the request name and timestamp need to be signed -- not all the uploaded bits (I guess Amazon doesn't want to spend the cycles on verifying all those bits either!). Below are the relevant code lines from Amazon's own "Introduction to AWS for C# Developers". Notice how Aws_GetSignature gets called only with "PutObject" and a timestamp? You could definitely implement the signature on your own web service without having to send the whole file and without compromising your key. In case you're wondering, Aws_GetSignature is a 9-line function that does a SHA1 hash on a concatenation of the constant string "AmazonS3", the operation name, and the RFC822 representation of the timestamp -- using your secret key.

    DateTime timestamp = Aws_GetDatestamp();
    string signature = Aws_GetSignature( "PutObject", timestamp );
    byte[] data = UnicodeEncoding.ASCII.GetBytes( content );
    service.PutObjectInline( "MainBucket", cAWSSecretKey, metadata,
            data, content.Length, null,
            StorageClass.STANDARD, true,
            cAWSAccessKeyId, timestamp, true,
            signature, null );
    

EDIT: note that while you can keep the secret key portion of your Amazon identity hidden, the access key ID portion needs to be embedded in the request. Unless you send the file through your own web service, you'll have to embed it in the app.

Oren Trutner
Thats pretty much it! To be honest, if the files are being loaded onto the internet, theres not much keeping me with a desktop app. Well, apart from my lack of asp knowledge, and the fact its easy to make a good looking app in winforms/wpf
Tim
Great! Your question is perfectly valid for web apps too, I believe, if they want to avoid sending the file twice (from browser to webapp, then from webapp to s3). Amazon's samples appear to skip that consideration sometimes.
Oren Trutner
A: 

Will you let anyone that gets a hold of a copy of your program access the data on S3/SimpleDB? If not, you will need your own authentication scheme that's independent from AWS security.

In that case, you could implement a web service that accepts the credentials that you give your customers (a username/password for example, a digital certificate, etc) and then performs the S3/SimpleDB operations that your program requires. That way, the AWS credentials never leave AWS. If a particular user's credentials are compromised, you can cancel those credentials in your web service.

Eric J.