0

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.

sevzas
  • 701
  • 2
  • 5
  • 13

1 Answers1

1

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:

enter image description here


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();
Topaco
  • 40,594
  • 4
  • 35
  • 62
  • This solution is working for me. I noticed that .net 7 has an ASN.1 parser in the System.Formats.Asn1 namespace that may eliminate the need to use BouncyCastle. – sevzas Nov 23 '22 at 20:42
  • @sevzas - You had mentioned .NET Framework in your question, and I mistakenly assumed you meant .NET Framework (4.8 or an earlier version). Starting with .NET 5 it is easier because PEM and ASN.1 parsing is supported. I have added a solution that applies to .NET5+. – Topaco Nov 24 '22 at 00:02
  • 1
    I did mean that I needed a solution for .Net Framework 4.8 and I used the BouncyCastle solution but I posted the additional about .Net 7 for anyone that comes across this question in the future and is using that version of .Net. – sevzas Nov 24 '22 at 11:23