.NET 4.0 DsaKeyValue required/optional parameter query for DSACryptoServiceProvider

StackOverflow https://stackoverflow.com/questions/14094255

  •  13-12-2021
  •  | 
  •  

سؤال

Im kinda confused about the required/optional requirement for loading XML for a DSACryptoServiceProvider.

From the this website, the following is the schema: Schema Definition:

   <element name="DSAKeyValue" type="ds:DSAKeyValueType"/> 
   <complexType name="DSAKeyValueType"> 
     <sequence>
       <sequence minOccurs="0">
         <element name="P" type="ds:CryptoBinary"/> 
         <element name="Q" type="ds:CryptoBinary"/>
       </sequence>
       <element name="G" type="ds:CryptoBinary" minOccurs="0"/> 
       <element name="Y" type="ds:CryptoBinary"/> 
       <element name="J" type="ds:CryptoBinary" minOccurs="0"/>
       <sequence minOccurs="0">
         <element name="Seed" type="ds:CryptoBinary"/> 
         <element name="PgenCounter" type="ds:CryptoBinary"/> 
       </sequence>
     </sequence>
   </complexType>

However, according to MSDN, the DsaKeyValue XML is defined as below:

<DSAKeyValue>

  <!-- Child elements -->
  P,
  Q,
  G?,
  Y,
  J?,
  Seed,
  PgenCounter

</DSAKeyValue>

Im getting a Bad data when importing from XML. Following is my code:

JsonDictionary privateKeyDictionary = (JsonDictionary) JsonReader.Parse(privateKey);
//FYI: this private signing key was generated using Keyczar.

var dsaParameterArray = privateKeyDictionary["publicKey"] as JsonDictionary;

    DSACryptoServiceProvider signer = new DSACryptoServiceProvider(1024);

    var pArray = Encoding.UTF8.GetBytes(dsaParameterArray["p"].ToString());
    string p = Convert.ToBase64String(pArray);

    var qArray = Encoding.UTF8.GetBytes(dsaParameterArray["q"].ToString());
    string q = Convert.ToBase64String(qArray);

    var gArray = Encoding.UTF8.GetBytes(dsaParameterArray["g"].ToString());
    string g = Convert.ToBase64String(gArray);

    var yArray = Encoding.UTF8.GetBytes(dsaParameterArray["y"].ToString());
    string y = Convert.ToBase64String(yArray);
    
    xml = String.Format("<DSAKeyValue><P>{0}</P><Q>{1}</Q><G>{2}</G><Y>{3}</Y><J/><Seed/><PgenCounter/></DSAKeyValue>", p, q, g, y);
    doc = new XmlDocument();
    doc.LoadXml(xml);
    signer.FromXmlString(doc.InnerXml);

All that said, my problem is that I dont have "J", "Seed" and "PgenCounter" in my key hence I didnt supply them. According to the W3C, thats optional. However, I do have a "x" in my key but wasnt sure what that was.

According to the W3C the Seed and PgenCounter tags are optional. However, the MSDN defines it as required.

Ive tried removing the J, Seed and PgenCounter tags and that didnt seem to help.

Thanks!

هل كانت مفيدة؟

المحلول

Here is an example output from Mono for a test Dsa key I generated for this example:

<DSAKeyValue
    <P>jTBkDXQ38ZCYNzCK8gmweKsJ/mTqtDkf9TMNJnJycC4Hel2B/owSoOBGclAXhFLkvGqOC+zz8uMz7X2K31rvTpFxhTD7j6MDiVkjQEhFIacb6+TUn71x0KdN3nZo0CR8QgkkU10bkjHq2409S34pU6d8fZaMUFyOFZtSbkxFGV8=</P>
    <Q>6N/tEzeK0DS5nS/PBg944efSlPs=</Q>
    <G>OCsUHXdniP4HpLV537LsaetSI3DQRI8dyQUOdhpCFk00t+/Sadokn2rt0dYkL1KCGTc74Z9fXpCKA0ae3aqh63GvV6Uznjn8Mm75jeS9O03YyNmTMKTi1mcTFVipLanaWskqR9o3+DaTY6Puk7UkL9dDEsF+njAE412DCihej0Q=</G>
    <Y>gjzX/7ggD8ax1inJv+7GsDNcLWr7wvxLvBETO0BxrMYABP4cH4xF/w63dghNgXOSEFKZ8SFQZpdDhG6LLlysIzOW/KvEE/L2/xkT4tWZUAhxYkVbdjfphVkH4IVqrKbpUUsHcTj/7qc7FtEepWLlywIMNW3dTeeaP3DuKnMIn7w=</Y>
    <J>mzWoXBr+3jptO5/JOYh+bNckQgwuwHhCyqbGCJotoVpZzTts10rWEOdf0wQGtWTCXnpU/so1P8S6ZItvflYJxX77fZxv9iEOLcaNIUwBbgv2Jf5kRFx9xAz0yafHQTSyzZJW7bcc+mU2SaG6</J>
    <Seed>NfC0CEI+/bzAnuyGgUo2PHTLyw8=</Seed>
    <PgenCounter>OA==</PgenCounter>
    <X>pK0LlCD6PLynniOKtW/S+iyR3F8=</X>
</DSAKeyValue>

This includes the private parameters. If I only included the public parameters, the output is:

<DSAKeyValue>
    <P>6run4SADV/kR/oEUmYXCTIqwWHG9yE+vMlnAbh4+I1YYTTCZ7Mf9BKZ6Z4WlSk+7WcnX+idT0HI5lOht+f5p32Z7aV86f89fLz4FTB+6r5B/cF8hhNe3mdGVpzzInwh2o16H9ejaB4chgOMASgeeBdNSzgVfj2RRWOZVX8wXWKU=</P>
    <Q>mfCvMD98ObtyBO1bJ6rIno2Wxws=</Q>
    <G>kgwCcpUWTyGaps8P/ePGj+CZUKSl2kxeJUSABYkgOa5I7OVIWrEgNl5fxCrs7qjXwJ+P+hQFe3HeHZWXONGgHpuakvDtp+G0wXuNUIF4vVwmZ0ff63TMFHGdUQXhsJPtK4ZK3LppSvWXACSzvZETH35A79nm4WRXlAIcHpxyeyg=</G>
    <Y>3fUEqW303wicxGJwsq1DoGKtvNUc3Eo33fpsdHMtZj+SyOH5ihvgKE7qd8yQxZH5qMI+5SFTokdwD8lh1jwmIq+Rrf2hi3RjZqNx+Lf3c6xRW3vDZSeTKwW/2xPiA+5z1rpO1/o2Bo5vV8i0ML3ik0VZasNVouo3C9KSX7Ya2cw=</Y>
    <J>AAAAAYZbcc5kA7nb5725pbY/qaTakYrxutdCZKEbtFu8KeXYFLCyw3FWlhmvMsStoAkleCnop0bBIoI3FLSEq5ZqUGcBfpNsV4qCs6tKcS7aZ8OFWpXncrYF1pwpaKpdzjDCaV69CEgkDCdQHw4gbA==</J>
    <Seed>n6ylLBasoS2Xqoc+QvBAXxQaFsc=</Seed>
    <PgenCounter>Dg==</PgenCounter>
</DSAKeyValue>

Notice the missing 'X' value which is the private key.

You should not be trying to parse these manually. Instead, use the DsaCryptoServiceProvider.FromXmlString method. Also, unless I am misreading the output this is compatible with the W3C standard, notwithstanding my comment above.

EDIT

Here is the code I used to generate the key. Bear in mind this was using Mono on Mac OS X, but I think it will work the same in .NET on Windows.

using System;
using System.Security.Cryptography;

namespace DsaParametersToy
{
    class MainClass
    {
        public static void Main (string[] args)
        {
            var dsa = new DSACryptoServiceProvider(1024);
            var dsaparams = dsa.ToXmlString(false);
            Console.WriteLine (dsaparams);
        }
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top