Summary
Enhance the Java Card API to perform key agreement using the Blinded Diffie-Hellman (BDH) protocol (EMV® Contactless Book E Security and Key Management v1.1).
Goals
The Java Card API already defines a KeyAgreement class that can be used for most of the key agreement schemes. However, the Blinded Diffie-Hellman scheme has specificities which require adapting the existing API. The goal is to offer an extension of the existing KeyAgreement API to support the Blinded Diffie-Hellman scheme.
Motivation
The Blinded Diffie-Hellman protocol is now being used in some payment systems to establish the secure channel between a payment card and a payment terminal. Providing direct support in the platform API enables efficient implementations that meet contactless transaction performance requirements.
Description
The Blinded Diffie-Hellman (BDH) scheme differs from other schemes in that the first party (typically the card) sends a Blinded Public Key instead of its Public Key. This requires generating a random blinding factor "r", which is multiplied by the first party’s public key to produce the Blinded Public Key sent to the second party. Additionally, the shared secret is computed using the private key and the other party’s public key multiplied by the same blinding factor "r". The other party (typically the payment terminal) performs a standard key exchange using the received Blinded Public Key.
Here are the operations performed with this API:
-
Creation of the KeyAgreement instance able to generate a shared secret and a Blinded Public Key
This uses the standard
KeyAgreementclass extended with an additional constant referring to the Blinded Diffie-Hellman scheme from EMV® Contactless Book E Security and Key Management v1.1.KeyAgreement ka = KeyAgreement.getInstance(ALG_EC_BDH_SECP256R1); -
Initialization of the KeyAgreement instance
Initialize the
KeyAgreementinstance by providing only the private key as follows.ka.init(PrivateKey);The corresponding public key will be retrieved from the private key and automatically computed internally. For performance reasons, an implementation may compute and store the public key rather than deferring it to the
generateSecret(...)call. -
Key exchange operation
Upon receiving the other party’s public key, you can generate a new blinding factor "r" and use it to compute both the Blinded Public Key and the shared secret. Because the blinding factor and the Blinded Public Key must be sent to the other party, the API provides methods to retrieve them.
This can be done using the new
BDHKeyAgreementinterface:((BDHKeyAgreement)ka).generateSecret( byte[] publicData, short publicOffset, short publicLength, byte[] secret, short secretOffset, byte[] blindedPublicKey, short blindedPublicKeyOffset, byte[] blindingFactor, short blindingFactorOffset);
.