none
Key not valid for use in specified state...what do you mean?

    Question

  • Hey Peoples!

     

    I imported a public key for the RSACryptoServiceProvider using the FromXMLString() method, which imports without drama, but throws an unhandled CryptographicException when I use the Encrypt() method, with the Error Message of "Key not valid for use in specified state."

     

    Does anyone understand this problem or how to get around it? I've looked at other forum posts but they all concern ASP, my application is a Windows Application built with C#, but out of desparation I have already tried the ASP fixes suggested but I still get the exception.

     

    Ok, and now some new observations of this annoying behaviour...

    I have just tried encrypting something using the same RSA Key Values XML string in the C# application that originally output the XML string and it works fine, but when I use the RSA Key Values XML in the application that did not generate the RSA Key Values XML it continues to throw the exception when I call the Encrypt method.

     

    So the question is, why bother allowing users to export RSA Key Values to XML when it doesn't work with anything but the application that originally created the XML??? ...and why is this not documented anywhere? I have spent hours on this problem. Why would there be security measures in place that limit the usefulness of the output XML to a single application?

     

    Microsoft people, please help me understand why I get this problem!!! There's a stack trace for the exception at the bottom. Is my current understanding correct, being "the values in the XML file are somehow tainted by the application that generated them, so that they can only be used with that particular application and no other" ?

     

    Keenly awaiting some clarity,

    Voss

     

     

    System.Security.Cryptography.CryptographicException was unhandled
      Message="Key not valid for use in specified state.\r\n"
      Source="mscorlib"
      StackTrace:
           at System.Security.Cryptography.CryptographicException.ThrowCryptogaphicException(Int32 hr)
           at System.Security.Cryptography.Utils._EncryptKey(SafeKeyHandle hPubKey, Byte[] key)
           at System.Security.Cryptography.RSACryptoServiceProvider.Encrypt(Byte[] rgb, Boolean fOAEP)
           at Project.Library.LicenseKey.EncryptAll_SPub(Byte[] data) in C:\Documents and Settings\Voss\My Documents\Visual Studio 2005\Projects\Project.Library\Project.Library\LicenseKey.cs:line 356
           at Project.Library.LicenseKey.Save(String fileName) in C:\Documents and Settings\Voss\My Documents\Visual Studio 2005\Projects\Project.Library\Project.Library\LicenseKey.cs:line 200
           at PWin.ActivateProduct.GenerateUnsignedKey() in C:\Documents and Settings\Voss\My Documents\Visual Studio 2005\Projects\Project.Library\PWin\ActivateProduct.cs:line 143
           at PWin.ActivateProduct.button1_Click(Object sender, EventArgs e) in C:\Documents and Settings\Voss\My Documents\Visual Studio 2005\Projects\Project.Library\PWin\ActivateProduct.cs:line 70
           at System.Windows.Forms.Control.OnClick(EventArgs e)
           at System.Windows.Forms.Button.OnClick(EventArgs e)
           at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
           at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
           at System.Windows.Forms.Control.WndProc(Message& m)
           at System.Windows.Forms.ButtonBase.WndProc(Message& m)
           at System.Windows.Forms.Button.WndProc(Message& m)
           at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
           at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
           at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
           at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
           at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
           at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
           at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
           at System.Windows.Forms.Form.ShowDialog(IWin32Window owner)
           at System.Windows.Forms.Form.ShowDialog()
           at PWin.Program.Main() in C:\Documents and Settings\Voss\My Documents\Visual Studio 2005\Projects\Project.Library\PWin\Program.cs:line 47
           at System.AppDomain.nExecuteAssembly(Assembly assembly, String[] args)
           at System.Runtime.Hosting.ManifestRunner.Run(Boolean checkAptModel)
           at System.Runtime.Hosting.ManifestRunner.ExecuteAsAssembly()
           at System.Runtime.Hosting.ApplicationActivator.CreateInstance(ActivationContext activationContext, String[] activationCustomData)
           at System.Runtime.Hosting.ApplicationActivator.CreateInstance(ActivationContext activationContext)
           at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssemblyDebugInZone()
           at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
           at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
           at System.Threading.ThreadHelper.ThreadStart()

    Friday, May 04, 2007 6:51 AM

Answers

  • Oh my god!!!

     

    I was totally off the mark, this problem has nothing to do with keys, much unlike what the exception message reports.

     

    I'm on my 2nd day of troubleshooting this problem and I finally found a useful article:

    http://www.novolocus.com/index.php?cat=code

     

    It turns out the guy is right, if you have more than 245 bytes in your byte array that you pass to your

    RSACryptoServiceProvider.Encrypt(byte[] rgb, bool fOAEP) method then it will throw an exception.

     

    This has severe limitations on the entire usefulness of the RSA implementation in dot net.

    What it means is you can encrypt data so long as it is 245 bytes or less (if your modulus is 256 bytes in size and you use PKCS1v1.5

     

    Too bad if you want to use it for something more.

     

    Microsoft people, can we get on comment on this? Is this an implementation problem? I've never had problems in the past with data limitations using cryptography before. It was my understanding that data was broken into manageable blocks and run through the underlying encryption algorithm. Why is RSACryptoServiceProvider so severely restricted?

    Friday, May 04, 2007 10:28 PM
  • Hi Voss Burton,

       There seems to be some problem with the implementation of System.Security.Cryptography.

       This is a known issue we are aware of. Currently our developers are investigating it.

     

       There is a explanation on this issue from the .Net security blog. Hope it can help you.

       http://blogs.msdn.com/shawnfa/rss_tag_Cryptography.xml

     

    Thanks!

    Wednesday, May 09, 2007 2:47 AM

All replies

  • Oh my god!!!

     

    I was totally off the mark, this problem has nothing to do with keys, much unlike what the exception message reports.

     

    I'm on my 2nd day of troubleshooting this problem and I finally found a useful article:

    http://www.novolocus.com/index.php?cat=code

     

    It turns out the guy is right, if you have more than 245 bytes in your byte array that you pass to your

    RSACryptoServiceProvider.Encrypt(byte[] rgb, bool fOAEP) method then it will throw an exception.

     

    This has severe limitations on the entire usefulness of the RSA implementation in dot net.

    What it means is you can encrypt data so long as it is 245 bytes or less (if your modulus is 256 bytes in size and you use PKCS1v1.5

     

    Too bad if you want to use it for something more.

     

    Microsoft people, can we get on comment on this? Is this an implementation problem? I've never had problems in the past with data limitations using cryptography before. It was my understanding that data was broken into manageable blocks and run through the underlying encryption algorithm. Why is RSACryptoServiceProvider so severely restricted?

    Friday, May 04, 2007 10:28 PM
  • Hi Voss Burton,

       There seems to be some problem with the implementation of System.Security.Cryptography.

       This is a known issue we are aware of. Currently our developers are investigating it.

     

       There is a explanation on this issue from the .Net security blog. Hope it can help you.

       http://blogs.msdn.com/shawnfa/rss_tag_Cryptography.xml

     

    Thanks!

    Wednesday, May 09, 2007 2:47 AM
  • Hello Feng Chen and Everyone else,

     

    Thanks for your reply. It is good to know that the developers are aware of this issue, hopefully it can be fixed in future patches (although I am concerned that support will quickly fade for .Net 2.0 and predecessors with the introduction of Vista, .Net 3.0, CTP Orcas and with time a new visual studio release(if not already...)).

     

    The .Net Security Blog has interesting information, however I did not find any quick fix to my problem and ended up implementing a custom system of encrypting and decrypting friendly sized byte arrays and joining them together for a single file transfer and processing with a perl script on a linux platform running an apache server. The end result has been a challenging journey learning that RSA is just not RSA on every combination of platform and implementation.

     

    If anyone out there is planning on using the .Net implementation of RSA for cross application/platform development for the exchange of RSA encrypted data, I would urge you don't  unless you have solid knowledge of, or the capacity (mental, time, financial) for many hours of studying information on topics including: The RSA algorithm itself, RSACryptoServiceProvider and it's limitations, RSAParameter, byte arrays (manipulations and conversions), big-endian encoding, UTF-8 encoding, big integer classes, OAEP, PKCS1v15 padding and signature schemes, to name a few.

     

    That's my two cents based on my experiences.

    Voss Burton.

     

    p.s. Don't believe the reasons given for CryptographicException, they are very misleading.

    Wednesday, May 09, 2007 7:23 AM
  • Just a note, the URL Voss gave above is no longer right - please use http://www.novolocus.com/2006/12/21/rsacryptoserviceprovider-key-not-valid-for-use-in-specified-state/ instead.

    It's worth noting, as mentioned in my post, you should use RSA encryption on to encrypt the key for a block cipher, and then use a block cipher (like AES) to encrypt your actual data. RSA is computationally expensive, but has obvious advantages related in having a public key. Block ciphers are fast, and handle lots of data, but rely on a shared password. Therefore, use RSA to share the password, and AES or alternative to encrypt the actual data.

    But it is a totally spurious exception. A better exception would be useful
    Wednesday, May 07, 2008 2:00 PM
  • Yes, could not agree more.

    Don't be using RSA for large amounts of data. Use it in combination of your real workhouse block cipher of your choice (aes, twofish, etc). Use rsa, gen your key, pass the public. login and or generate block cipher key (or let server do it). do initial handshake with RSA, then scrap RSA and use your symmetric block cipher thereafter.

    if you were to be writing a client server platform and were to test the scalability of RSA for all packet encryption you would be horrified as it compares to the block ciphers.

    also check out BountyCastle.com

    i modified their large c# library down to rsa and a few block ciphers as these are not working in silverlight at the moment and may never as the CLR is so whittled down in silverlight.
    • Proposed as answer by Giftednewt Wednesday, October 01, 2008 9:15 AM
    Saturday, September 20, 2008 11:13 AM
  • Yes, could not agree more.

    Don't be using RSA for large amounts of data. Use it in combination of your real workhouse block cipher of your choice (aes, twofish, etc). Use rsa, gen your key, pass the public. login and or generate block cipher key (or let server do it). do initial handshake with RSA, then scrap RSA and use your symmetric block cipher thereafter.

    if you were to be writing a client server platform and were to test the scalability of RSA for all packet encryption you would be horrified as it compares to the block ciphers.

    also check out BountyCastle.com

    i modified their large c# library down to rsa and a few block ciphers as these are not working in silverlight at the moment and may never as the CLR is so whittled down in silverlight.
    Saturday, September 20, 2008 11:13 AM
  •  RSACryptoServiceProvider MyRSAAsymmetricAlgorithmDef = new RSACryptoServiceProvider();
    int theSizeDefault = MyRSAAsymmetricAlgorithmDef.KeySize;//should return 1024 bits (128 bytes)

    /* if the encrypted/decripted byte array exceedes this the exception is thrown.
    Try to extend the size in the constructor but larger sizes tend to timeouts
    */

    RSACryptoServiceProvider MyRSAAsymmetricAlgorithm = new RSACryptoServiceProvider(4096);
    int theCurrentKeySize = MyRSAAsymmetricAlgorithm.KeySize; //now the 512 bytes may be encrypted/decripted

    Friday, January 09, 2009 3:05 PM
  • Thursday, November 10, 2011 4:21 PM
  • The original hungarian translation: "a kulcs nem használható a megadott államban". In that meaning "állam" not equals "state". Állam means like the word in "United States".
    Tuesday, August 07, 2012 11:06 AM
  • Oh my god!!!

     

    I was totally off the mark, this problem has nothing to do with keys, much unlike what the exception message reports.

     

    I'm on my 2nd day of troubleshooting this problem and I finally found a useful article:

    http://www.novolocus.com/index.php?cat=code

     

    It turns out the guy is right, if you have more than 245 bytes in your byte array that you pass to your

    RSACryptoServiceProvider.Encrypt(byte[] rgb, bool fOAEP) method then it will throw an exception.

     

    This has severe limitations on the entire usefulness of the RSA implementation in dot net.

    What it means is you can encrypt data so long as it is 245 bytes or less (if your modulus is 256 bytes in size and you use PKCS1v1.5

     

    Too bad if you want to use it for something more.

     

    Microsoft people, can we get on comment on this? Is this an implementation problem? I've never had problems in the past with data limitations using cryptography before. It was my understanding that data was broken into manageable blocks and run through the underlying encryption algorithm. Why is RSACryptoServiceProvider so severely restricted?


    This also depents on what keysize u use. Like for 512 you can only encrypt up to 46 bytes! This sucks btw.
    Wednesday, January 09, 2013 4:02 PM