Skip to main content
Home
for DLMS smart meters
Open source solutions for DLMS smart metering

Main navigation

  • Home
  • Products
  • About us
  • Open Source
  • Community
  • Forum
  • Downloads
User account menu
  • Log in

Breadcrumb

  1. Home
  2. Forums
  3. Key Agreement Using Ephermal Keys

Key agreement using Ephermal keys

Forum Rules

Before commenting read Forum rules

Don't comment the topic if you have a new question.

You can create a new topic selecting correct category from Gurux Forum and then create a new topic selecting "New Topic" from the top left.

By Siemens-US , 5 April, 2018
Forums
Gurux DLMS for Java

Hi

We want to use key agreement feature of DLMS COSEM to exchange new keys with the meter. In this type we need to use ephermal key pair(for public key ) and a signing key pair(for private key). How these keys will be generated? Will these be provided to me by the manufacturer or will we randomly generate these?

Thanks
Yatin

Profile picture for user Kurumi

Kurumi

8 years 2 months ago

Key agreement using

Hi,

You can generate those keys with the framework. It was a little surprise that Java does not support it.
There is an example how to generate certificate on unit test but I'll copy it here:
/*
* Key agreement test.
*/
@Test
public final void keyAgreementTest() throws Exception {
target.getCiphering().setSecurity(Security.AUTHENTICATION_ENCRYPTION);
target.getProposedConformance().add(Conformance.GENERAL_PROTECTION);
// Generate keys for the client.
target.getCiphering().setSigningKeyPair(getClientTestSigningKeyPair());
target.getCiphering()
.setSystemTitle(GXCommon.hexToBytes("4D4D4D0000BC614E"));
target.getCiphering().setRecipientSystemTitle(
GXCommon.hexToBytes("4D4D4D0000000001"));

server = new TestServer(new GXDLMSAssociationLogicalName(),
InterfaceType.WRAPPER);
server.getCiphering()
.setSystemTitle(GXCommon.hexToBytes("4D4D4D0000000001"));
target.getCiphering().setInvocationCounter(0x0123456789012345L);
server.getCiphering().setInvocationCounter(0x0123456789012345L);
GXDLMSClock clock = new GXDLMSClock();
GXDLMSSecuritySetup ss = new GXDLMSSecuritySetup();
server.getItems().add(clock);
server.getItems().add(ss);
server.initialize();
GXReplyData info = new GXReplyData();
byte[] reply = server.handleRequest(target.aarqRequest()[0]);
info.clear();
target.getData(reply, info);
assertEquals(0, info.getError());
target.parseAareResponse(info.getData());

////////////////////////////////////////////////////////////////
// Generate signing keys.
Date from = new Date();
Date to = new Date(from.getTime() + 365L * 24L * 60L * 60L * 1000L);
// Create client certificate for digital signature.
GXx509Certificate certificate =
GXx509Certificate.createSelfSignedCertificate(
target.getCiphering().getSigningKeyPair(), from, to,
target.getCiphering().getSystemTitle(),
"CN=Test, O=Gurux, L=Tampere, C=FI", KeyUsage.forValue(
(KeyUsage.DIGITAL_SIGNATURE.getValue())));

// Send client's digital signature to the server.
reply = server
.handleRequest(ss.importCertificate(target, certificate)[0]);
info.clear();
target.getData(reply, info);
assertEquals(0, info.getError());
////////////////////////////////////////////////////////////////
// Create server certificate and export it.
reply = server.handleRequest(ss.generateKeyPair(target,
CertificateType.DIGITAL_SIGNATURE)[0]);
info.clear();
target.getData(reply, info);
assertEquals(0, info.getError());
// Note! This is not used. We are using signing key pair from Green Book
// C1.
server.getCiphering().setSigningKeyPair(getServerTestSigningKeyPair());

reply = server.handleRequest(ss.generateCertificate(target,
CertificateType.DIGITAL_SIGNATURE)[0]);
info.clear();
target.getData(reply, info);
assertEquals(0, info.getError());
GXPkcs10 cert = new GXPkcs10((byte[]) info.getValue());

certificate = GXx509Certificate.createSelfSignedCertificate(
server.getCiphering().getSigningKeyPair(), from, to,
cert.getSubject(), "CN=Test, O=Gurux, L=Tampere, C=FI",
KeyUsage.forValue((KeyUsage.DIGITAL_SIGNATURE.getValue())));

// Send server's digital signature to the server.
reply = server
.handleRequest(ss.importCertificate(target, certificate)[0]);
info.clear();
target.getData(reply, info);
assertEquals(0, info.getError());

// Export server's certificate.
reply = server.handleRequest(target.getServerCertificate(ss,
CertificateType.DIGITAL_SIGNATURE)[0]);
info.clear();
target.getData(reply, info);
assertEquals(0, info.getError());
certificate = new GXx509Certificate((byte[]) info.getValue());

// Disconnect.
reply = server.handleRequest(target.disconnectRequest());
info.clear();
target.getData(reply, info);
assertEquals(0, info.getError());

/////////////////////////////////////////////////////////////////
// Change security suite 1 after signature is sent to the server.
target.setSecuritySuite(SecuritySuite.ECDH_ECDSA_AES_GCM_128_SHA_256);
reply = server.handleRequest(target.aarqRequest()[0]);
// target.getCiphering().getPublicKeys()
// .add(new GXSimpleEntry<CertificateType, PublicKey>(
// CertificateType.DIGITAL_SIGNATURE,
// cert.getPublicKey()));

info.clear();
target.getData(reply, info);
assertEquals(0, info.getError());
target.parseAareResponse(info.getData());
// Generate client's Ephemeral keys and send it to the server.
target.getCiphering()
.setEphemeralKeyPair(getClientEphemeralKeyPairC1());
server.getCiphering()
.setEphemeralKeyPair(getServerEphemeralKeyPairC1());
reply = server.handleRequest(
ss.keyAgreement(target, GlobalKeyType.UNICAST_ENCRYPTION)[0]);
info.clear();
target.getData(reply, info);
assertEquals(0, info.getError());
target.getSharedSecret((byte[]) info.getValue(),
certificate.getPublicKey());

// Check shared secret.
byte[] z = GXCommon.hexToBytes(
"C1 CF 8F E7 89 1A EF 36 17 D7 19 07 95 E6 1F E6 C2 4E FC 3C CA 2E 08 46 9B AD 1A 22 5C E6 EA 08");

// Client generates shared secret.
KeyAgreement ka = KeyAgreement.getInstance("ECDH");
ka.init(target.getCiphering().getEphemeralKeyPair().getPrivate());
ka.doPhase(target.getSettings().getTargetEphemeralKey(), true);
byte[] actual = ka.generateSecret();
assertEquals(GXCommon.toHex(z), GXCommon.toHex(actual));
reply = server.handleRequest(target.read(clock, 2)[0]);
info.clear();
target.getData(reply, info);
assertEquals(0, info.getError());
}

BR,

Mikko

  • Create new account
  • Reset your password

Hire Us!

Latest Releases

  • Tue, 06/09/2026 - 11:16
    gurux.dlms.java 4.0.95
  • Tue, 06/09/2026 - 10:03
    Gurux.DLMS.Python 1.0.199
  • Mon, 06/08/2026 - 13:39
    gurux.dlms.cpp 9.0.2606.0801
  • Mon, 06/01/2026 - 10:15
    gurux.dlms.cpp 9.0.2606.0101
  • Thu, 05/28/2026 - 16:06
    gurux.dlms.java 4.0.94

New forum topics

  • Error reading L&G Meter
  • Pass a TCP Client to GXNet
  • Australian EDMI Mk10D (Essential Energy area)
  • Strange mix of data notificiation vs get response
  • DLMS Connection
More

Who's new

  • Tuanhgg
  • Adel
  • charnon
  • Paddles
  • Miguel Ángel
RSS feed
Privacy FAQ GXDN Issues Contact
Follow Gurux on Twitter Follow Gurux on Linkedin