none
RSA ImportParameters is generating Intermittent "The parameter is incorrect" error message for Exponent values of 3, 5, and 17 RRS feed

  • Question

  • The following code intermittently generates an “The parameter is incorrect” error message for the  RSA.ImportParameters(RSAParms) statement for Exponent values of 3, 5 and 17.  Exponent values of 257 and 65537 do not generate the error message.

             RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(rsaKeySize);

             try

             {

                RSAParameters RSAParms = RSA.ExportParameters(true);

                RSAParms.Exponent = Exponent;

                RSA.ImportParameters(RSAParms);

             }

             catch (Exception err)

             {

                ptrMsgQueues.clsErrorQueue.Enqueue("RSA Exception = " + err.Message + "\r\n" + errorMsg);

             }

    I have also seen this error for an exponent of 257 but it is very infrequent.


    • Edited by Bob Bryant Tuesday, August 6, 2019 6:16 PM
    Thursday, August 1, 2019 10:44 PM

All replies

  • Hi Bob,

    Thank you for posting here.

    Based on your description, you want to solve the exception when you use RSA.ImportParameters method.

    If you want to use this method, I think it is best for you to create a new RSACryptoServiceProvider to accept RSAParameters.

    I make a simple code, you could have a look.

                 try
                {
                    using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(2048))
                    {
                        RSAParameters RSAParams = RSA.ExportParameters(true);
                        byte[] m = { 3,5,17};
                        RSAParams.Exponent = m;
    
                        //Create another RSACryptoServiceProvider object.
                        using (RSACryptoServiceProvider RSA2 = new RSACryptoServiceProvider())
                        {
                            RSA2.ImportParameters(RSAParams);
                        }
                    }
                }
                catch (CryptographicException e)
                {
                    
                    Console.WriteLine(e.Message);
                }

    If you want to know more about it, you could refer to RSACryptoServiceProvider.ImportParameters(RSAParameters) Method.

    Best Regards,

    Jack



    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Friday, August 2, 2019 2:48 AM
    Moderator
  • Thanks for your response.

    I add your code to my function call and I get the same error message intermittently.  Also I want to pass in the individual exponent value of 3, 5, 17, 257, or 65377 not a byte array of {3,5,17}.

    thanks

    Tuesday, August 6, 2019 8:43 PM
  • Hi Bob,

    Thanks for the feedback.

    >>Also I want to pass in the individual exponent value of 3, 5, 17, 257, or 65377 not a byte array of {3,5,17}.

    According to this article, I find RSAParams.Exponent is a type of byte array instead of single number.

    If you used the following code, you will get the error that Cannot implicitly convert type 'int' to 'byte[]'.

     RSAParams.Exponent = 3;

    Therefore, I want to know what is your initial code about it.

    Best Regards,

    Jack


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, August 7, 2019 5:43 AM
    Moderator
  • Thanks for the response

    I am familiar with the requirement that the RSA exponent needs to be in a byte array.  I found the problem running a regressing test that used an exponent value of 3 and did not fail in May 2019.  The only differences in the test environment between May 2019 and now are Windows and VS updates.

     

    The intermit failure is highest for and exponent of 3 and decreases as the exponent values get larger (5, 17 and 257).  The exponent value of 257 rarely fails.  I have never seen the exponent value 65377 fail.

    If the failure decreases linearly with increasing exponent value it would take 1000s of calls the RSA function to generate the failure for and exponent value of 65377.

     

    The RSA function is running in a thread and receives the RSA key size and exponent values in a queue.  The parameters are extracted from the queue and converted to their required data types by the code shown below as you requested.

     

    =========================================================================

    // extract key size from the queue

    int rsaKeySize = localPtDataConveters.getInt(ptrMsgQueues.clsMsgQueue.Dequeue());

     

    // extract exponent from the queue

    int rsaExponent = localPtDataConveters.getInt(ptrMsgQueues.clsMsgQueue.Dequeue());

     

    // convert exponent to a byte array and convert to Big Endian if necessary

    byte[] Exponent = BitConverter.GetBytes(rsaExponent);

    if (BitConverter.IsLittleEndian) Array.Reverse(Exponent);

     

    Try

    {

          // create instances of RSACryptoServiceProvider with the user supplied key size

          RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(rsaKeySize);

          // get rsa paramters

          RSAParameters RSAParms = RSA.ExportParameters(true);

                   

         try

           {

              // add exponent bit array

              RSAParms.Exponent = Exponent;

              // import RSA parameters

              RSA.ImportParameters(RSAParms); // fails intermittently generating an “The parameter is incorrect” error message

           }

               catch (Exception err)

              {

                 // return error message in the error queue

                 ptrMsgQueues.clsErrorQueue.Enqueue("RSA Exception = " + err.Message + "\r\n" + errorMsg);

              }

    }

    catch (Exception err)

    {

       ptrMsgQueues.clsErrorQueue.Enqueue("RSA Exception = " + err.Message + "\r\n");

    }

    Thursday, August 8, 2019 8:18 PM
  • Hi Bob,

    Thanks for the feedback.

    ImportParameters method have two reasons to throw this CryptographicException. One is “The cryptographic service provider (CSP) cannot be acquired”. Another is “The parameters parameter has missing fields”. See this link for more information. 

    The first solution, try the below code.

    RSACryptoServiceProvider.UseMachineKeyStore = True

    If it doesn’t work, please try the second solution. The error message shows that CSP missed parameter fields. Please refer to the page and test the example.
    https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.cspparameters?redirectedfrom=MSDN&view=netframework-4.8

    Best Regards,

    Jack


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Friday, August 9, 2019 6:32 AM
    Moderator
  • Thanks Jack

    I tried your suggestion and I get the same results. I also moved the RSA code from the working thread to my main thread and again I get the same intermittent error.   I have tried the code in the link you suggested, added my update to the exponent and receive the same intermittent error.  To date I have not found an example where the parameters RSACryptoServiceProvider are exported, the exponent modified, and then imported back in.  This is starting to look like a real error in RSACryptoServiceProvider.

    Monday, August 12, 2019 3:49 PM