Guroo guroo

Guroo guroo

  • NA
  • 1
  • 0

RSACryptoServiceProvider Can't access private keys to decrypt

Apr 25 2007 11:52 PM

Hi,
I am trying to use RSACryptoServiceProvider in my ASP.NET application to access keys from a MachineKeyStore on my computer, running windows xp and IIS 5.
I created machinekeystore like following in Visual Studio 2005 Command Prompt:

aspnet_regiis -pc "CustomKeys" -exp (command was successful)

Then I executed following command because I am impersonating my web application with a non-default user:

aspnet_regiis -pa "CustomKeys" "domain\auserforapplication" (command was successful)

Then I worte the following code:

<code>public partial class Examples_EncryptionExample : System.Web.UI.Page
{
    CspParameters CspParam;
    string publicXmlString = string.Empty;
    string privateXmlString = string.Empty;
    protected void Page_Load(object sender, EventArgs e)
    {
        try
        {
            byte []  encrypted;
            string decrypted;

            UnicodeEncoding ByteConverter = new UnicodeEncoding();
            encrypted = EncrptData("data to encrypt");
            Response.Write(System.Text.Encoding.Unicode.GetString(encrypted));
            decrypted = DecryptData(encrypted);
            Response.Write(decrypted);
        }
        catch (Exception ex)
        {
        }
    }

    public string DecryptData(byte [] data)
    {
        RSACryptoServiceProvider RsaCsp;
        byte[] decryptedData;
        RsaCsp = new RSACryptoServiceProvider();
        RsaCsp.FromXmlString(privateXmlString);
        decryptedData = RsaCsp.Decrypt(data, false);
        return System.Text.Encoding.Unicode.GetString(decryptedData);
    }

    public byte [] EncrptData(string data)
    {
        RSACryptoServiceProvider RsaCsp;
        RSACryptoServiceProvider RsaCsp2;
        UnicodeEncoding ByteConverter = new UnicodeEncoding();
        CspParam = new CspParameters();
        CspParam.KeyContainerName = "CustomKeys";
        CspParam.Flags = CspProviderFlags.UseMachineKeyStore;

        byte[] encryptedData = ByteConverter.GetBytes(data);

        RsaCsp = new RSACryptoServiceProvider(CspParam);

        //Getting public key
        publicXmlString = RsaCsp.ToXmlString(false);
        //Getting private key
        privateXmlString = RsaCsp.ToXmlString(true);

        RsaCsp2 = new RSACryptoServiceProvider();
        RsaCsp2.FromXmlString(publicXmlString);
        encryptedData = RsaCsp2.Encrypt(System.Text.Encoding.Unicode.GetBytes(data), false);

        return encryptedData;
    }
}</code>

The problem over here is that when ever I try to execute the above mentioned code. Code encrypts the data fine
but when it comes at decrypting the data, throws following exception:

Exception Details: System.Security.Cryptography.CryptographicException: The system cannot find the file specified.


<code>Source Error:


Line 35:         byte[] decryptedData;
Line 36:         RsaCsp = new RSACryptoServiceProvider();
Line 37:         RsaCsp.FromXmlString(privateXmlString);
Line 38:         decryptedData = RsaCsp.Decrypt(data, false);
Line 39:         return System.Text.Encoding.Unicode.GetString(decryptedData);
 

Source File: c:\Data\iis\www\DefaultWeb\Phoenix\Admin\Examples\EncryptionExample.aspx.cs    Line: 37

Stack Trace:


[CryptographicException: The system cannot find the file specified.
]
   System.Security.Cryptography.CryptographicException.ThrowCryptogaphicException(Int32 hr) +33
   System.Security.Cryptography.Utils._CreateCSP(CspParameters param, Boolean randomKeyContainer, SafeProvHandle& hProv) +0
   System.Security.Cryptography.Utils.CreateProvHandle(CspParameters parameters, Boolean randomKeyContainer) +201
   System.Security.Cryptography.RSACryptoServiceProvider.ImportParameters(RSAParameters parameters) +262
   System.Security.Cryptography.RSA.FromXmlString(String xmlString) +465
   Examples_EncryptionExample.DecryptData(Byte[] data) in c:\Data\iis\www\DefaultWeb\Phoenix\Admin\Examples\EncryptionExample.aspx.cs:37
   Examples_EncryptionExample.Page_Load(Object sender, EventArgs e) in c:\Data\iis\www\DefaultWeb\Phoenix\Admin\Examples\EncryptionExample.aspx.cs:28
   System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +15
   System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +34
   System.Web.UI.Control.OnLoad(EventArgs e) +99
   System.Web.UI.Control.LoadRecursive() +47
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1061</code>

I could control the above mentioned error by doing a nasty trick which is. The account "domain\auserforapplication" which I am impersonating my application with. I used a utility in windows xp accessible from "All Programs/Accessories/System Tool/Schedule Tasks" to create a process e.g. executed calc.exe application under the account "domain\auserforapplication". Everything started working fine. No error nothing.

A million dollar question is why did I get the above mentioned error at the first place? Why did I had to start a new process under the indentity of my application on my machine.

If somebody could answer my question. I will highly appreciate that because then I have another question regarding exporting the keys to Windows 2003 Server and using keys over there. That problem is even nasty.

For now I will highly appriciate if somebody could answer my current question.
Thanks