title: Why is RSAParameters Modulus not equal product of P and Q?
body: <p>The values of P and Q do not match value of the Modulus of the .Net RSAParameters.
  According to RSA algorithm and MSDN documentation it should be: P * Q = Modulus</p>
  
  <p>I generated a 512bit RSA keypair and exported it to XML by invoking:</p>
  
  <pre><code>RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(512);
  rsa.ToXmlString(true);
  </code></pre>
  
  <p>This gave me the following XML:</p>
  
  <pre><code>&lt;RSAKeyValue&gt;
    &lt;Modulus&gt;rcLI1XTfmXtX05zq67d1wujnUvevBu8dZ5Q5uBUi2mKndH1FZLYCKrjFaDTB/mXW1l5C74YycVLS6msY2NNJYw==&lt;/Modulus&gt;
    &lt;Exponent&gt;AQAB&lt;/Exponent&gt;
    &lt;P&gt;1dwGkK5POlcGCjQ96Se5NSPu/hCm8F5EYwyqRpLVzgk=&lt;/P&gt;
    &lt;Q&gt;0AAEMHBj7CP2XHfCG/RzGldw1GdsW13rTo3uEE9Dtws=&lt;/Q&gt;
    &lt;DP&gt;PO4jMLV4/TYuElowCW235twGC3zTE0jIUzAYk2LiZ4E=&lt;/DP&gt;
    &lt;DQ&gt;ELJ/o5fSHanBZCjk9zOHbezpDNQEmc0PT64LF1oVmIM=&lt;/DQ&gt;
    &lt;InverseQ&gt;NyCDwTra3LiUin05ZCGkdKLwReFC9L8Zf01ZfYabSfQ=&lt;/InverseQ&gt;
    &lt;D&gt;EWwFTPmx7aajULFcEJRNd2R4xSXWY8CX1ynSe7WK0BCH42wf/REOS9l8Oiyjf587BhGa3y8jGKhUD7fXANDxcQ==&lt;/D&gt;
  &lt;/RSAKeyValue&gt;
  </code></pre>
  
  <p>Now I successfully wrote a litte test programm to encrypt, decrypt, sign and verify data.</p>
  
  <p>At the end I added a little test code:</p>
  
  <pre><code>RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(512);
  rsa.FromXmlString(key); // key = string with XML above
  
  RSAParameters param = rsa.ExportParameters(true);
  BigInteger p = new BigInteger(param.P);
  BigInteger q = new BigInteger(param.Q);
  BigInteger n = new BigInteger(param.Modulus);
  BigInteger myN = BigInteger.Multiply(p, q);
  Console.WriteLine("n   = " + n.ToString());
  Console.WriteLine("myN = " + myN.ToString());
  </code></pre>
  
  <p>Which gave we the following output:</p>
  
  <pre><code>n   = 5200154866521200075264779234483365112866265806746380532891861717388028374942014660490111623133775661411009378522295439774347383363048751390839618325234349
  
  myN = 23508802329434377088477386089844302414021121047189424894399694701810500376591071843028984420422297770783276119852460021668188142735325512873796040092944
  </code></pre>
  
  <p>Why does multiplying P and Q not equal the Modulus?</p>
  
  <p>I already checked a lot of things like endian, encoding, BigInteger class, successfully encrypted, decrypted, signed, verified with the above XML keys but cannot find any explanation why P and Q multiplied is not equaling the Modulus...</p>
  
  <p>Can anybody help me explain why P*Q is not the Modulus ?</p>
  
  <p>All values in readable format:</p>
  
  <pre><code>Modulus  = 5200154866521200075264779234483365112866265806746380532891861717388028374942014660490111623133775661411009378522295439774347383363048751390839618325234349
  Exponent = 65537
  P  = 4436260148159638728185416185189716006279182659244174640493183003717504785621
  Q  = 5299238895894527538601438806093945941831432623367272568173893997325464109264
  DP = -57260184070162652127728137041376572684067529466727954512100856352006444159428
  DQ = -56270397953566513533764063103154348713259844205844432469862161942601135050224
  InverseQ = -5297700950752995201824767053303055736360972826004414985336436365496709603273
  D = 5967761894604968266284398550464653556930604493620355473531132912985865955601309375321441883258487907574824598936524238049397825498463180877735939967118353
  </code></pre>
  
  <p><strong>UPDATE</strong>:</p>
  
  <p>According to the answer I wrote a little extension method for the .Net BigInteger class to work correctly with the RSAParameters:</p>
  
  <pre><code>public static class BigIntegerExtension
  {
      public static BigInteger FromBase64(this BigInteger i, string base64)
      {
          byte[] p = Convert.FromBase64String(base64).Reverse().ToArray();
          if (p[p.Length - 1] &gt; 127)
          {
              Array.Resize(ref p, p.Length + 1);
              p[p.Length - 1] = 0;
          }
         return new BigInteger(p);
      }
  
      public static BigInteger FromBigEndian(this BigInteger i, byte[] p)
      {
          p = p.Reverse().ToArray();
          if (p[p.Length - 1] &gt; 127)
          {
              Array.Resize(ref p, p.Length + 1);
              p[p.Length - 1] = 0;
          }
          return new BigInteger(p);
      }
  }
  </code></pre>
  
  <p>Usage example:</p>
  
  <pre><code>BigInteger modulus1 = new BigInteger().FromBase64("rcLI1XTfmXtX05zq67d1wujnUvevBu8dZ5Q5uBUi2mKndH1FZLYCKrjFaDTB/mXW1l5C74YycVLS6msY2NNJYw==");
  
  BigInteger modulus2 = new BigInteger().FromBigEndian(param.Modulus);
  </code></pre>
  
  <p>Hope this helps others with the same problem :-)</p>