3

this is my first question and first post in english so please by patience with me.

I'm working on ASP.NET MVC Web Api RESTful application. For user authentication I want to use encrypted tokens. My idea that works on localhost: User ask for token address/Token, in header include auth: nickname:passwd and server returns encrypted token that user will using it in every next request. So user send request with header auth-token: encryptedToken and server will decrypt this token and authenticate user. On my localhost works everything perfectly well. After upload to the server: (ASP.NET 4.0 for free users) I ask for my token, server response with this token (everything ok now) and than I'll make next request and include my token in header, server try to decrypt it and there it crashes. I know, that it crashes in part where I set RSACryptoServiceProvider his private key (set public key on encrypt works well). Here is my code of my RSAHelper which I use for it:

public class RSAHelper
{
    private static string _privateKey = "<?xml version=\"1.0\" encoding=\"utf-16\"?>\r\n<RSAParameters xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">\r\n  <Exponent>AQAB</Exponent>\r\n  <Modulus>rrEAoxIBFkfvoLr8vvT2Z3CKHKtpXiAPIYKbgtiP/B8YAOhDo1W3dD4MKX05eXn0jFifXBoy2WbGTacE88NocXoSUWVH4a7d3Bm4hfeNawfSSHEpkO0xryU6xF0PdfqO+Vc6y9gajYugUkAdougqaall4TwjsfZ/XUVl6GkTOws=</Modulus>\r\n  <P>zDkpvahctB77Hx/4W1Yfp5rCC3B7rL9CHvf+L1rQdEgooK2NI4Nz6uTixgTTmyRSLRdGLIZRAjAUVFNdYaIbCw==</P>\r\n  <Q>2vsc41/NtLKoCwUtuXyvx4o0c3/RNVLws3VpQ2Ct+2kHt15siO9IwCTTQPgbUi52e8cbh7w3wwWoLwsugAdgAQ==</Q>\r\n  <DP>DcOYhZjQTq9721grQ/SlA4XRqDW3kCf/y9iJACYNwJiQbGvmBEu6x00P36q5nE4xX6qe5ydSVGRrKlfIBmmHiw==</DP>\r\n  <DQ>uhlOo613lGmAhl0QTuK4QEwj50Ro93hVNy5BFxHCyjaoaB3G/1jb6u9g2YYBMgZqiybbLq+2c/cKx3ApRIUAAQ==</DQ>\r\n  <InverseQ>H0BA/DVxNa/JukiqHYe+xuYtblCL04o7pCoAvx/5BFBqHAFOP8Vg0R16WNNoABUGDRTYe7AkWUAquqW9uVWaLw==</InverseQ>\r\n  <D>LGyCtvVrJVlhzMQAZicxShjKZoQIpZENh/4IwfuEkh7uIbzvBmhT4NGukhZwOT4UPGSFEgzvhW2nXDPvBHZa5qT/JknF0juT/B6goa+suMjYupAYk/8oIJuF8ez9MWQ1Blouc+/6Gxoh8tRsRpixoRXbX0kUrz8DdEgjSxp8gAE=</D>\r\n</RSAParameters>";
    private static string _publicKey = "<?xml version=\"1.0\" encoding=\"utf-16\"?>\r\n<RSAParameters xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">\r\n  <Exponent>AQAB</Exponent>\r\n  <Modulus>rrEAoxIBFkfvoLr8vvT2Z3CKHKtpXiAPIYKbgtiP/B8YAOhDo1W3dD4MKX05eXn0jFifXBoy2WbGTacE88NocXoSUWVH4a7d3Bm4hfeNawfSSHEpkO0xryU6xF0PdfqO+Vc6y9gajYugUkAdougqaall4TwjsfZ/XUVl6GkTOws=</Modulus>\r\n</RSAParameters>";
    private static UnicodeEncoding _encoder = new UnicodeEncoding();

    public static string Decrypt(string data)
    {
        try
        {
            var bytesCypherText = Convert.FromBase64String(data);

            //rsa.FromXmlString(_privateKey);
            //get a stream from the string
            var sr = new System.IO.StringReader(_privateKey);
            //we need a deserializer
            var xs = new System.Xml.Serialization.XmlSerializer(typeof(RSAParameters));
            //get the object back from the stream
            var privKey = (RSAParameters)xs.Deserialize(sr);
            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
            rsa.ImportParameters(privKey); //-------- here is the problem 
            var bytesPlainTextData = rsa.Decrypt(bytesCypherText, false);

            //get our original plainText back...
            var plainTextData = System.Text.Encoding.Unicode.GetString(bytesPlainTextData);
            return plainTextData;
        }
        catch (Exception)
        {
            throw new RSAException(); 
        }
    }

    public static string Encrypt(string data)
    {
        try
        {
            var rsa = new RSACryptoServiceProvider();
            //rsa.FromXmlString(_publicKey);
            //get a stream from the string
            var sr = new System.IO.StringReader(_publicKey);
            //we need a deserializer
            var xs = new System.Xml.Serialization.XmlSerializer(typeof(RSAParameters));
            //get the object back from the stream
            var pubKey = (RSAParameters)xs.Deserialize(sr);
            rsa.ImportParameters(pubKey);
            var dataToEncrypt = System.Text.Encoding.Unicode.GetBytes(data);
            var bytesCypherText = rsa.Encrypt(dataToEncrypt, false);
            return Convert.ToBase64String(bytesCypherText);

        }
        catch (Exception ex)
        {
            throw new RSAException();
        }
    }

    public class RSAException : Exception
    {
        public RSAException() : base("RSA Encryption Error") { }
    }
}

Sorry for a little bit mess there, but I'm trying to solve my problem and I'm very desperate. After 2 days no progress at all, still the same problem in the same place!

I was trying 3 tutorials or tips: http://msdn.microsoft.com/cs-cz/library/system.security.cryptography.rsacryptoserviceprovider(v=vs.110).aspx

C# RSA encryption/decryption with transmission

How to do role based authorization for asp.net mvc 4 web api

I will be very grateful for any help

EDIT// After long googling there are some posts about similar problem. For private key I need permissions FULL TRUST and actually I have shared server. Are there any modern solutions to make it works under shared server? Posts about:

http://www.codeproject.com/Articles/20950/Using-RSA-Public-Key-Encryption-in-a-Shared-Web-Ho
and
http://forums.asp.net/t/983896.aspx
Community
  • 1
  • 1
Stepan Sanda
  • 2,322
  • 7
  • 31
  • 55
  • Please post exception details – Den Pakizh Nov 13 '13 at 23:01
  • UnfortunatelyI can't get exception details, others exceptions in program catch this and returned HTTP/1.1 401 Unauthorized. I'll try to get this exception detail but I don't know how to do it :-( PS: I edited my post with new google resutls. The problem might be in my shared server permissions right? – Stepan Sanda Nov 13 '13 at 23:58
  • Yes, that is most likely cause. Unfortunately, you can't use crypto api in shared environment. – Den Pakizh Nov 14 '13 at 00:31
  • Yeah it seems to be like that. So maybe is there any other option how can I encrypt token, send it to user and then decrypt it back for user authentization? Is it possible to use symmetric crypto where is only one key for example? – Stepan Sanda Nov 14 '13 at 06:29
  • I'd suggest to use Bouncy Castle instead: http://www.bouncycastle.org/csharp/ – Den Pakizh Nov 14 '13 at 11:38

1 Answers1

3

So problem was solved! And here is solution for others who will have the same problem :-)

In my case administrator of my shared server is reasonable man and set me higher trust level, so everything starts working :-)

For those who hasn't got this option to set higher trust level there is another option very easy to implement: http://www.codeproject.com/Articles/20950/Using-RSA-Public-Key-Encryption-in-a-Shared-Web-Ho It works in the same way as RSACryptoServiceProvider include the same name of methods. Just add this library to your project and rename RSACryptoServiceProvider to EZRSA :)

Stepan Sanda
  • 2,322
  • 7
  • 31
  • 55