Search code examples
javac#encodingx509certificatebouncycastle

BouncyCastle Encoding differences


I'm trying to calculate the hash of a public key to match what ApplePay is giving me. I can't get BouncyCastle in C# to give me the public key in the right format so I can hash it. However the Java version that I'm porting works just fine. OpenSSL also gives the right response, but I'd prefer not to have to deal with OpenSSL as well as BC to do this.

Java: (works)

ECPublicKey key = (ECPublicKey) certificate.getPublicKey();
byte[] keyBytes = key.getEncoded(); 

MessageDigest messageDigest = MessageDigest.getInstance("SHA256", PROVIDER_NAME);
byte[] keyHash = messageDigest.digest(keyBytes);    

String base64keyBytes = new String(Base64.encode(keyBytes));
//base64keyBytes == MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE+4wQWWRnPqGlsncZX17t0CfLOl6u
// 68aXUsqnzlIcpCdDukHhxibd2MjHPFGpnK3ZKdHxIFh+NBQvGssM5ncm1g==
// line break added for readability

OpenSSL: (works)

openssl x509 -noout -pubkey -in <file> -inform der 
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE+4wQWWRnPqGlsncZX17t0CfLOl6u
68aXUsqnzlIcpCdDukHhxibd2MjHPFGpnK3ZKdHxIFh+NBQvGssM5ncm1g==
-----END PUBLIC KEY-----

C#: (keyBytes are wrong)

SubjectPublicKeyInfo pubinfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(certificate.GetPublicKey());
byte[] keyBytes = pubinfo.GetEncoded();

byte[] keyHash = DigestUtilities.CalculateDigest("SHA_256", keyBytes);

string keyBytesEncoded = Convert.ToBase64String(keyBytes);
/*keyBytesEncoded == MIIBKjCB4wYHKoZIzj0CATCB1wIBATAsBgcqhkjOPQEBAiEA/////wAAAAEAAA
AAAAAAAAAAAAD///////////////8wWwQg/////wAAAAEAAAAAAAAAAAAAAAD/
//////////////wEIFrGNdiqOpPns+u9VXaYhrxlHQawzFOw9jvOPD4n0mBLAx
UAxJ02CIbnBJNqZnjhE50mt4GffpAEIQNrF9Hy4SxCR/i85uVjpEDydwN9gS3r
M6D0oTlF2JjClgIhAP////8AAAAA//////////+85vqtpxeehPO5ysL8YyVRAg
EBA0IABPuMEFlkZz6hpbJ3GV9e7dAnyzperuvGl1LKp85SHKQnQ7pB4cYm3djI
xzxRqZyt2SnR8SBYfjQULxrLDOZ3JtY=
line break added for readability */

What is the right way to port the GetEncoding?

I know it's the key data that wrong because when I manually force in the data from openssl I get the right hash.

EDIT: Added the out puts.


Solution

  • I think it would just be:

    byte[] keyBytes = certificate.CertificateStructure.SubjectPublicKeyInfo.GetDerEncoded()