Thursday, January 21, 2010

RSA-SHA1 Signature

After enabling the users to explore their S3 accounts in AWS using
CloudBuddy, our development team got into exploring Cloud Front Private
Content feature which will enable the users to share their content(s) in
secure manner.

To know more about Cloud Front Private Content feature:
http://docs.amazonwebservices.com/AmazonCloudFront/latest/DeveloperGuide/index.html?PrivateContent.html

Since Amazon provides the private key in PEM file format, our technology
research associates got into identifying ways to generate an URL with
RSA-SHA1 private key signing. They are unable to come out with a sequence
of steps which will facilitate in generating the private key using C#.

After a couple of days, our Open Source Specialist highlighted a solution
in Linux based system using SSL feature. The next challenges is to convert
that code into windows compatible. After a indepth understanding of logic
involved in generation private keys, we provide below our four step
methodology of builiding it using Open SSL in C++ and some wrapper for C#.

Step 1: Converting PEM as XML

As C# method takes the private signature key as a XML file we had converted
PEM file into XML using the C# code provided in the following link
http://csslab.s3.amazonaws.com/csslabs/Siva/opensslkey.cs

Step 2: SHA1 Hashing

The hash string has to be computed for the Policy (in CloudBuddy it  can be
any string that need to be encrypted)

      string strPolicy = "{\"Statement\":[{\"Resource\":\"http://*\

      ",\"Condition\":{\"IpAddress\":{\"AWS:SourceIp\":\"0.0.0.0/0
\"},\"DateLessThan\":{\"AWS:EpochTime\":1261153938}}}]}\n"; // String to be
signed
            byte[] buffer = Encoding.ASCII.GetBytes(strPolicy);
            SHA1CryptoServiceProvider cryptoTransformSHA1 = new
SHA1CryptoServiceProvider();
            buffer = cryptoTransformSHA1.ComputeHash(buffer);

Step 3 : Signing

Generated SHA1 Hash has to be signed using RSA algorithm with the Private
Key which is provided by Amazon. As we have already converted the PEM file
into an XML content it is a easy task to sign the policy hash string with
Private Key using the following code

            RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
            XmlDocument xmlPrivateKey = new XmlDocument();
            xmlPrivateKey.Load(@"D:\PEM.xml"); // PEM.xml has been
generated out from Step 1
            RSA.FromXmlString(xmlPrivateKey.InnerXml);
            RSAPKCS1SignatureFormatter RSAFormatter = new
RSAPKCS1SignatureFormatter(RSA);
            RSAFormatter.SetHashAlgorithm("SHA1");
            byte[] SignedHash = RSAFormatter.CreateSignature (buffer) ;

Now you have signed policy so you are all set to use it right away? NO...
there is one more step ahead to get the result what is that?

Step 4: Encoding

Signed hash string has to be encoded as form 64, which can be achieved by
following code:

      string strSignedPolicy = System.Convert.ToBase64String(SignedHash );

The above generated code (strSignedPolicy) need to be appended with the
generated URL which helps in private sharing of contents.

Example:-
http://d2qgjra4ybtnjf.cloudfront.net/Videos/20051210-w50s.flv?Expires=1274534865&Signature=cnJh3q5dgAkMYYcjCItXn6u49Z56A5Lc1Ti8uVZBRQn3NDRlxorlrhzyqvzid~JCOqGhCTQMDWOBzM5XtS0jrF2VD2ljETaKH1FdOKfVoJ0c51fIpyRxio67yloyq4E7lkhVqIP0DxdVnyUEATU9E6NEElKch2UABJ4ys3jItjU_&Key-Pair-Id=APKAJW3NCIJJGAVSTATQ

Out of which query string Signature has been generated using above
mechanism.

2 comments:

rsa private key said...

Hey ! This is great. Thanks for sharing all steps point by point. I tried it as your told and didn't get any problem any where. Fantastic tutorial..would love to read more things from your side.

data recovery san francisco said...

Excellent post I was checking constantly this blog and I’m inspired! Very helpful info.