Generating subject public key info in a compressed form

EC Compressed Public Key - OpenSSL BouncyCastle Apple VAS NFC

When implementing Apple VAS (Value Added Services) or NFC-based loyalty/payment systems, one common requirement is generating a Subject Public Key Info (SPKI) in compressed form. This is essential for embedding the public key in Apple Wallet passes and NFC terminal configurations.

This post covers three approaches: using OpenSSL, the dotnet-passbook library, and BouncyCastle for C#.

Why Use Compressed Public Keys?

EC (Elliptic Curve) public keys can be represented in two formats:

  • Uncompressed: Contains both X and Y coordinates (65 bytes for P-256)
  • Compressed: Contains only the X coordinate + a prefix byte (33 bytes for P-256)

Apple VAS and many NFC terminals require the compressed format to save space on the NFC chip.

Step 1: Generate Compressed Public Key with OpenSSL

If you have an existing EC private key in PEM format, use the following OpenSSL command to export the compressed public key:

openssl ec -in private_key.pem -pubout -out compressed_public_key.pem -conv_form compressed

This produces a PEM file containing the SPKI with the compressed point encoding.

Step 2: Use the Key with dotnet-passbook (Apple Wallet NFC)

When using the dotnet-passbook library to generate Apple Wallet passes with NFC support, pass the Base64-encoded compressed key to the Nfc constructor:

request.Nfc = new Nfc("15407F6", @"MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgAC/O3/C07TB7WkJuUZ1vZkAn4LZs+IGUpy7BMnh1bKrBY=");

The first parameter is the message, and the second is the Base64-encoded DER-encoded compressed public key.

Step 3: Read and Encode with BouncyCastle in C#

If you need to do this programmatically in C#, BouncyCastle makes it straightforward:

PemReader pemReader = new PemReader(new StringReader(pemString));
ECPublicKeyParameters ecPublicParameters = (ECPublicKeyParameters)pemReader.ReadObject();

// Get compressed encoding (true = compressed, false = uncompressed)
byte[] compressed = ecPublicParameters.Q.GetEncoded(true);
byte[] uncompressed = ecPublicParameters.Q.GetEncoded(false);

// Convert to Base64 for use in NFC/VAS configurations
string compressedBase64 = Convert.ToBase64String(compressed);

Summary

Compressed public keys are a fundamental requirement for Apple VAS and NFC terminal integrations. Whether you use OpenSSL for one-off conversions or BouncyCastle for runtime key handling in C#, the process is straightforward once you understand the encoding differences. Always verify the key length — a valid P-256 compressed key is 33 bytes.

Post a Comment

Previous Post Next Post