Using C# to get the Public Key from my cert for Java

David Lozzi picture David Lozzi · Jan 21, 2013 · Viewed 10.3k times · Source

Without BounceyCastle.

I have my cert, and the GetPublicKey() value is not what the Java side of the house needs.

The cert if an X509Certificate2 object, using DSA encryption. Created using makecert

Convert.ToBase64String(cert.GetPublicKey()) returns

AoGAeaKLPS4ktxULg3YQL0ePphF08tKsddZtv3SDERa8b8go5h3AxmWjuDd8y9dIzZFe8KDjY9Lg
JU4JOA27snO3fCsPAVkmJ0O2pbxn+wzT7oij2FOLcCAjnFNNsoaWrtMv+I4XXl18DyDQLFkZiPx9
2UyuDzoQTGxgCrPccQPjUgY=

Convert.ToBase64String(cert.RawData) returns

MIICxjCCAoagAwIBAgIQbdIpaaU9rZdA+wJKA+mUfDAJBgcqhkjOOAQDMBYxFDASBgNVBAMTC0RT
QSBSb290IENBMB4XDTEzMDExMDE3MTAzNVoXDTM5MTIzMTIzNTk1OVowFDESMBAGA1UEAxMJVXNl
ciBOYW1lMIIBtzCCASwGByqGSM44BAEwggEfAoGBALWn4Iyvn7LFkV9ULoZtwJ8J1c+ibsbhjPiw
+xUgRW2LAZV2/Lv89W1jCprNkf87tN/ogMT/1VSIOo7ff/tqVRTWPVJ1ZMrR9VOnF2k/Sorg8Cmr
sAClsSWrACKIwK2XKJGWTU4oMLxvYcu85+yQ4nWLofgA/+WARrJ/rk2aUSZ3AhUAlqPLNh6JZkpD
G/OXKzhsZFUiDrkCgYEAoICjHltWOgN8/2uyAaMTNrBuJfi/HM9AWe5B8m9HDfl1K6Qx2Ni6tbYP
uFtvHdGnoqqn46l7eY+xjpi5GEydvkPtAQKmTDGcSh6vtnTeNV15Hafg5pXUKw1OisIr/bpx/KIk
cgCtSo6qC5IhDzeZXnfJYcE+8U+O6hEr5dwByN4DgYQAAoGAeaKLPS4ktxULg3YQL0ePphF08tKs
ddZtv3SDERa8b8go5h3AxmWjuDd8y9dIzZFe8KDjY9LgJU4JOA27snO3fCsPAVkmJ0O2pbxn+wzT
7oij2FOLcCAjnFNNsoaWrtMv+I4XXl18DyDQLFkZiPx92UyuDzoQTGxgCrPccQPjUgajWTBXMAwG
A1UdEwEB/wQCMAAwRwYDVR0BBEAwPoAQmhMLkJ/cPXGitvGMB81tZaEYMBYxFDASBgNVBAMTC0RT
QSBSb290IENBghDCpMJ75zgZokJVlZmNq/LTMAkGByqGSM44BAMDLwAwLAIUYUALM9WhgwzRMj1y
MSdoparmYvICFFxLgFr2ow3NGTkqWvHIXtjO9R0G

However, when my Java counterpart gets the public key, using the same cert file, gets

$ cat david-509.cer | openssl x509 -pubkey
-----BEGIN PUBLIC KEY-----
MIIBtzCCASwGByqGSM44BAEwggEfAoGBALWn4Iyvn7LFkV9ULoZtwJ8J1c+ibsbh
jPiw+xUgRW2LAZV2/Lv89W1jCprNkf87tN/ogMT/1VSIOo7ff/tqVRTWPVJ1ZMrR
9VOnF2k/Sorg8CmrsAClsSWrACKIwK2XKJGWTU4oMLxvYcu85+yQ4nWLofgA/+WA
RrJ/rk2aUSZ3AhUAlqPLNh6JZkpDG/OXKzhsZFUiDrkCgYEAoICjHltWOgN8/2uy
AaMTNrBuJfi/HM9AWe5B8m9HDfl1K6Qx2Ni6tbYPuFtvHdGnoqqn46l7eY+xjpi5
GEydvkPtAQKmTDGcSh6vtnTeNV15Hafg5pXUKw1OisIr/bpx/KIkcgCtSo6qC5Ih
DzeZXnfJYcE+8U+O6hEr5dwByN4DgYQAAoGAeaKLPS4ktxULg3YQL0ePphF08tKs
ddZtv3SDERa8b8go5h3AxmWjuDd8y9dIzZFe8KDjY9LgJU4JOA27snO3fCsPAVkm
J0O2pbxn+wzT7oij2FOLcCAjnFNNsoaWrtMv+I4XXl18DyDQLFkZiPx92UyuDzoQ
TGxgCrPccQPjUgY=
-----END PUBLIC KEY-----

And thus my problem. How do I get this value from my cert?

Thanks!

Answer

Alex Erygin picture Alex Erygin · Jul 4, 2017

You should use cert.PublicKey.EncodedKeyValue instead of cert.GetPublicKey().

EncodedKeyValue provides ASN1 encoded value, not raw key data as GetPublicKey().

So you can use this code

void ExportPublicKey(X509Certificate2 cert, string filePath)
{
    byte[] encodedPublicKey = cert.PublicKey.EncodedKeyValue.RawData;
    File.WriteAllLines(filePath, new[] {
        "-----BEGIN PUBLIC KEY-----",
        Convert.ToBase64String(encodedPublicKey, Base64FormattingOptions.InsertLineBreaks),
        "-----END PUBLIC KEY-----",
    });
}