Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Storing My Amazon Credentials in C# Desktop App

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.

UPDATE 2 - Sept 2011

Amazon have released some details on using the AWS Security Token Service, which allows for authentication without disclosing your secret key. More details are available on this blog post.

like image 684
Tim Avatar asked Jul 21 '09 18:07

Tim


People also ask

Where should AWS credentials be stored?

The AWS CLI stores sensitive credential information that you specify with aws configure in a local file named credentials , in a folder named . aws in your home directory. The less sensitive configuration options that you specify with aws configure are stored in a local file named config , also stored in the .

Can I encrypt AWS credentials file?

However - the credentials can be as well passed as env variables or cli/api parameters. These can be encrypted and decrypted or requested when to be used, but still you need access to the decryption key or service.

How do I secure my AWS credentials?

Create the RoleCreate a role and name it admin . For the role type, select “Role for Cross-Account Access” and “Provide access between AWS accounts you own”. Enter the same account ID for the account you're in (found in account settings) and check the “Require MFA” box.

Where are AWS credentials stored on EC2?

In this example output, the IAM user credentials are stored in the . aws/credentials file. Because these credentials have a higher precedence than role credentials, IAM user credentials are used to make API calls.


1 Answers

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.

like image 116
Oren Trutner Avatar answered Oct 08 '22 07:10

Oren Trutner