I generated a .pem file that contains Diffie-Hellman parameters. I used this command line:
openssl dhparam -outform PEM 2048 -out dhparam.pem
The file looks like this:
-----BEGIN DH PARAMETERS-----
MIIBCAKCAQEA6gS7LGwOkRMfJJX2sBK+NRwSL1OaegjVeEh+FJJbWRLG7pB9W7JX
[4 lines omitted]
7LyTYZEvaaAK27xuf4uo4YCFnaOkxp/R6wIBAg==
-----END DH PARAMETERS-----
How can I extract the Generator and Prime values from this file using .Net Framework code?
Note that there is an answer How to extract DH parameters from a DH key in PEM format for how to accomplish this task on the command line.
For .NET Framework it is most convenient to retrieve the data using BouncyCastle's Utilities.IO.Pem.PemReader
and ASN.1 parser:
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Utilities.IO.Pem;
using System;
using System.IO;
...
string dhParamsPem = @"-----BEGIN DH PARAMETERS-----
MIIBCAKCAQEAnyWVRlZpZ0P6aVzTS25m1SR+HqJAXsGqRhVSPlijljZ+8B/2d1m7
/HlyZIXIkRkgiBvarl7BK95Uj4A34+rabFaab0aukJm8DgI0Za3MuiPG2+1EsZPm
9IQnGo+VRXv/VZ4ooMUmOw/NLU3lJ4P8ViK9R+1e5OnLK3FWxQWFfidAhDnx8Xzc
vp8Y9qR0DuiQQc3cZaS0Ko+LDxqQJkHobsKdpdd2DGxdeRjg4f65j/WVixSEmSyI
rMwDu4svdk7Bjd9cjlSui3mm7Trf1ME0Ox18Ir5FRuzpZvkuD11oDF0fc3A2gCdx
hiuj5z75xtXMGqcTlzMicWTal6MtLfmWCwIBAg==
-----END DH PARAMETERS-----";
PemReader pemReader = new PemReader(new StringReader(dhParamsPem));
PemObject pemObject = pemReader.ReadPemObject();
Asn1Sequence asn1Seq = Asn1Sequence.GetInstance(pemObject.Content);
BigInteger p = ((DerInteger)asn1Seq[0]).PositiveValue;
BigInteger g = ((DerInteger)asn1Seq[1]).PositiveValue;
Console.WriteLine(p); // 20090423409171421154387714584555511320868268871945482725661544541530332355839089164300271096651615230651244725677611659751244269997811212265593049309472107745660505171223135113566045750129565437460985935927850461605237593196654771593662837177817015214051951556984885103642631543107288713880526529543092219393162039732425952951349374625402000680805514079485639328869699772680730890272312298949384709284994133124244952710119496271097947248984953575915669174208183280906980298889356605342059216347892537283618180485781467407114828705793629928947579235056616468247708144579207430255173737359957970195317686357288487065099
Console.WriteLine(g); // 2
The data can be checked with an ASN.1 online parser, e.g. https://lapo.it/asn1js:
Edit: As of .NET 5, e.g. the native classes PemEncoding
and AsnReader
can be used, so BouncyCastle is no longer needed:
using System;
using System.Formats.Asn1;
using System.Numerics;
using System.Security.Cryptography;
...
PemFields pemFields = PemEncoding.Find(dhParamsPem);
byte[] derData = Convert.FromBase64String(dhParamsPem[pemFields.Base64Data]);
AsnReader asn1Seq = new AsnReader(derData, AsnEncodingRules.DER).ReadSequence();
BigInteger p = asn1Seq.ReadInteger();
BigInteger g = asn1Seq.ReadInteger();