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 coppice, 14 April, 2015
In GXDLMS/COSEMDirector the manufacturer data can be set up for High, HighMD5, HighSHA1, and HighGMAC authentication. When this is done, and I connect to a meter, GXDLMS/COSEMDirector sends the correct context and a challenge string in an AARQ message. My meter sends back an AARE message containing an appropriate challenge string. However, GXDLMS/COSEMDirector doesn't go through the remaining steps to complete the challenge handshake. If I then click "read", GXDLMS/COSEMDirector sends a get message, which is rejected by the meter, because the handshake has not been completed. Am I doing something wrong, or is the implementation of high level authentication incomplete.
I realised that I had not set the acse-service-user in my AARE message to 14. This was stopping GXDLMSDirector from proceeding to stages 3 and 4 of the authentication handshake. With this fixed I get an action-request from GXDLMSDirector after I send it an AARE when I use MD5 or SHA1 authentication.
My next problem is the method-invocation-parameters field in the action-request seems wrong. Section 9.2.7.4 of the Green book says that I should feed the challenge string followed by the secret through SHA1 or MD5 to produce the method-invocation-parameters field. However, I can only match the field received from GXDLMSDirector if I pass the secret followed by the challenge string through SHA1 or MD5 (i.e. the reverse order).
When I use GMAC authentication and reply to an AARQ with any kind of AARE message GXDLMSDirector displays an error box saying "Object reference not set to an instance of an object" I tried to debug this, but the open source code on github.com is not up to date, and behaves differently when GMAC is used.
When I use SHA1 or MD5 I can now connect and click read to get the known objects from the meter. However, if I click read a second time I get an error box saying "Specified argument was out of the range of valid values".
What you call the Texas Instruments high level authentication comes from the India national DLMS spec (i.e. the spec which defines the set of objects which an Indian meter must support). Other people use it too. It was defined before the well defined MD5 and SHA1 authentications were added to the DLMS spec. The Kalkitech Explorer software also supports this, so the TI software is compatible with it. The algorithm is just to use a secret key to AES128 encrypt the challenge string, like so...
/* Encrypt the challenge that was sent to the client */
for (i = 0; i challenge_s2c_len/16; i++)
{
aes128_encrypt(&challenge_s2c[i*16], secret_key);
}
/* Encrypt the challenge that was sent by the client */
for (i = 0; i link->challenge_c2s_len/16; i++)
{
aes128_encrypt(&challenge_c2s[i*16], secret_key);
}
The encrypted challenge_s2c must match the one received from the client.
The encrypted challenge_c2s is sent back to the client.
I see that the installer for DLMSDirector has been updated to 7.0.43.1, and a few changes have been committed to the git repository. However, high level authentication is still very broken. MD5 and SHA1 authentication only work if the secret and challenge string are processed in the reverse order from the spec. GMAC authentication gives the error "Object reference not set to an instance of an object" because in GXDLMS.cs GXDLMSChipperingStream() is called with "null" for the iv parameter, while in the implementation of GXDLMSChipperingStream() in GXDLMSChipperingStream.cs iv is expected to point to a usable memory address.
The authentication in 4.0.75.1 doesn't work at all. I tried the code in the git repo, and with the following changes I can get it to work for the Indian style high level authentication, and MD5 and SHA1 authentication the way the green book defines it. Note that I am not a C# programmer, and the way I got the Indian style authentication to work is a nasty fudge. I assume there is a more elegant way to work step through a long challenge string as it is encrypted.
diff --git a/Development/GXDLMS.cs b/Development/GXDLMS.cs
index 512f013..05c72b2 100644
--- a/Development/GXDLMS.cs
+++ b/Development/GXDLMS.cs
@@ -161,8 +161,10 @@ static public byte[] Chipher(Authentication auth, byte[] challenge, byte[] secre
{
if (auth == Authentication.High)
{
- byte[] p = new byte[challenge.Length];
+ byte[] p = new byte[((challenge.Length + 15)/16)*16];
byte[] s;
+ int i;
+
if (secret.Length 16)
{
s = new byte[16];
@@ -173,8 +175,14 @@ static public byte[] Chipher(Authentication auth, byte[] challenge, byte[] secre
}
challenge.CopyTo(p, 0);
secret.CopyTo(s, 0);
- GXAes128.Encrypt(s, p);
- return s;
+ for (i = 0; i p.Length; i += 16)
+ {
+ byte[] x = new byte[16];
+ Buffer.BlockCopy(p, i, x, 0, 16);
+ GXAes128.Encrypt(x, s);
+ x.CopyTo(p, i);
+ }
+ return p;
}
if (auth == Authentication.HighMD5)
{
@@ -184,7 +192,7 @@ static public byte[] Chipher(Authentication auth, byte[] challenge, byte[] secre
challenge.CopyTo(tmp, 0);
secret.CopyTo(tmp, challenge.Length);
tmp = md5Hash.ComputeHash(tmp);
- Array.Reverse(tmp);
+ //Array.Reverse(tmp);
return tmp;
}
}
@@ -196,7 +204,7 @@ static public byte[] Chipher(Authentication auth, byte[] challenge, byte[] secre
challenge.CopyTo(tmp, 0);
secret.CopyTo(tmp, challenge.Length);
tmp = sha.ComputeHash(tmp);
- Array.Reverse(tmp);
+ //Array.Reverse(tmp);
return tmp;
}
}
diff --git a/Development/GXDLMSClient.cs b/Development/GXDLMSClient.cs
index 17db4dc..18d7005 100644
--- a/Development/GXDLMSClient.cs
+++ b/Development/GXDLMSClient.cs
@@ -816,7 +816,8 @@ public byte[][] GetApplicationAssociationRequest()
{
throw new ArgumentException("Password is invalid.");
}
- List CtoS = new List(Password);
+ //List CtoS = new List(Password);
+ List CtoS = new List();
if (m_Base.StoCChallenge != null)
{
CtoS.AddRange(m_Base.StoCChallenge);
@@ -875,7 +876,7 @@ public void ParseApplicationAssociationResponse(byte[] reply)
throw new Exception("Invalid challenge.");
}
byte[] serverChallenge = (byte[])GXCommon.GetData(arr.ToArray(), ref index, ActionType.None, out total, out read, ref type, ref CacheIndex);
- List challenge = new List(Password);
+ List challenge = new List();
challenge.AddRange(m_Base.CtoSChallenge);
byte[] clientChallenge = GXDLMS.Chipher(this.Authentication, challenge.ToArray(), Password);
int pos = 0;
The latest update to the DLMSDirector installer still fails to authenticate. Thanks for bringing the git repository up to date. I was able to find fixes for the Indian mode 2 authentication, MD5, and SHA1. I haven't tried to fix GMAC yet. Apply the following patches to GXCom/Protocols/Gurux.DLMS.Net:
diff --git a/Development/GXDLMS.cs b/Development/GXDLMS.cs
index 25e8c16..70a49db 100644
--- a/Development/GXDLMS.cs
+++ b/Development/GXDLMS.cs
@@ -161,8 +161,10 @@ static public byte[] Chipher(Authentication auth, byte[] challenge, byte[] secre
{
if (auth == Authentication.High)
{
- byte[] p = new byte[challenge.Length];
+ byte[] p = new byte[((challenge.Length + 15) / 16) * 16];
byte[] s;
+ int i;
+
if (secret.Length 16)
{
s = new byte[16];
@@ -173,8 +175,14 @@ static public byte[] Chipher(Authentication auth, byte[] challenge, byte[] secre
}
challenge.CopyTo(p, 0);
secret.CopyTo(s, 0);
- GXAes128.Encrypt(s, p);
- return s;
+ for (i = 0; i p.Length; i += 16)
+ {
+ byte[] x = new byte[16];
+ Buffer.BlockCopy(p, i, x, 0, 16);
+ GXAes128.Encrypt(x, s);
+ x.CopyTo(p, i);
+ }
+ return p;
}
if (auth == Authentication.HighMD5)
{
diff --git a/Development/GXDLMSClient.cs b/Development/GXDLMSClient.cs
index 1f731b5..a267ba3 100644
--- a/Development/GXDLMSClient.cs
+++ b/Development/GXDLMSClient.cs
@@ -816,7 +816,7 @@ public byte[][] GetApplicationAssociationRequest()
{
throw new ArgumentException("Password is invalid.");
}
- List CtoS = new List(Password);
+ List CtoS = new List();
if (m_Base.StoCChallenge != null)
{
CtoS.AddRange(m_Base.StoCChallenge);
@@ -875,7 +875,7 @@ public void ParseApplicationAssociationResponse(byte[] reply)
throw new Exception("Invalid challenge.");
}
byte[] serverChallenge = (byte[])GXCommon.GetData(arr.ToArray(), ref index, ActionType.None, out total, out read, ref type, ref CacheIndex);
- List challenge = new List(Password);
+ List challenge = new List();
challenge.AddRange(m_Base.CtoSChallenge);
byte[] clientChallenge = GXDLMS.Chipher(this.Authentication, challenge.ToArray(), Password);
int pos = 0;
There has been an update to the git code, and the installer says it has been updated to 7.0.48.1, but it hasn't. The installer which can be downloaded is still 7.0.47.1.
The git code still has problems with encrypted authentication. The following diff fixes this:
diff --git a/Development/GXDLMS.cs b/Development/GXDLMS.cs
index 2fff595..6a87004 100644
--- a/Development/GXDLMS.cs
+++ b/Development/GXDLMS.cs
@@ -161,23 +161,20 @@ static public byte[] Chipher(Authentication auth, byte[] challenge, byte[] secre
{
if (auth == Authentication.High)
{
- byte[] p = new byte[challenge.Length + 15];
- byte[] s = new byte[16];
- byte[] x = new byte[16];
+ byte[] p = new byte[((challenge.Length + 15) / 16) * 16];
+ byte[] s = new byte[(secret.Length 16) ? 16 : secret.Length];
int i;
- if (secret.Length 16)
- {
- challenge.CopyTo(p, 0);
- secret.CopyTo(s, 0);
- for (i = 0; i p.Length; i += 16)
- {
- Buffer.BlockCopy(p, i, x, 0, 16);
- GXAes128.Encrypt(x, s);
- x.CopyTo(p, i);
- }
- return p;
+
+ challenge.CopyTo(p, 0);
+ secret.CopyTo(s, 0);
+ for (i = 0; i p.Length; i += 16)
+ {
+ byte[] x = new byte[16];
+ Buffer.BlockCopy(p, i, x, 0, 16);
+ GXAes128.Encrypt(x, s);
+ x.CopyTo(p, i);
}
- throw new ArgumentException("Chipher failed. Invalid secret.");
+ return p;
}
if (auth == Authentication.HighMD5)
{
diff --git a/Development/GXDLMSClient.cs b/Development/GXDLMSClient.cs
index 046b5e0..78bd857 100644
--- a/Development/GXDLMSClient.cs
+++ b/Development/GXDLMSClient.cs
@@ -816,7 +816,7 @@ public byte[][] GetApplicationAssociationRequest()
{
throw new ArgumentException("Password is invalid.");
}
- List CtoS = new List(Password);
+ List CtoS = new List();
if (m_Base.StoCChallenge != null)
{
CtoS.AddRange(m_Base.StoCChallenge);
@@ -875,7 +875,7 @@ public void ParseApplicationAssociationResponse(byte[] reply)
throw new Exception("Invalid challenge.");
}
byte[] serverChallenge = (byte[])GXCommon.GetData(arr.ToArray(), ref index, ActionType.None, out total, out read, ref type, ref CacheIndex);
- List challenge = new List(Password);
+ List challenge = new List();
challenge.AddRange(m_Base.CtoSChallenge);
byte[] clientChallenge = GXDLMS.Chipher(this.Authentication, challenge.ToArray(), Password);
int pos = 0;
There was some strange thing happened in our Continous Installation system and
new version did not come to our web page. Souce codes was updated to the github as they should be.
After the major updates between version 7 and 8 of DLMSDirector the code seems to be settling down, but I still have problems with authentication in version 8.0.0.8. If I try to use MD5 authentication over a TCP connection my meter receives the following AARQ message from DLMSDirector:
This starts with an 8 byte IEC62056-47 header. The password "aaaaaaaaaaaaaaaa" has been sent as clear text in the calling-authentication-value field, and the user-information field seems completely messed up. When I try SHA1 authentication I get a similar result.
You are right. We made some changes for GMAC authentication and now we are accidentally send
dedicated key and do not run MD5 or SHA1 for password. We will fix this and release new version during this week.
Version 8.0.0.9 gets things a bit farther. However, when I try MD5 or SHA1 authentication, and my meter responds to the AARQ from DLMSDirector with status 14, DLMSDirector says "Object reference set to an instance of an object". An example message exchange is as follows:
When I tried uninstalling 8.0.0.9 I found the Windows control panel "Programs and Features" page list several earlier versions of DLMSDirector, as well as 8.0.0.9. It seems the update process in DLMSDirector isn't clearing out older versions during update. I removed all the versions I could find, and reinstalled 8.0.0.9. I still get the same result, as follows, for an attempt to use MD5 authentication:
Version 8.0.0.12 of DLMSDirector fixes the problems I was experiencing with 8.0.0.9, but now I find a similar problem to one I reported earlier. The Green Book says the way to calculate the SHA1 authentication values is SHA-1(StoC || HLS Secret) and SHA-1(CtoS || HLS Secret). DLMSDirector seems to be applying the strings to the SHA-1 algorithm in the reverse order, i.e. SHA-1(HLS Secret || StoC) and SHA-1(HLS Secret || CtoS). If I modify my meter code to use the order the DLMSDirector is using, the authentication steps work. MD5 shows this same issue, of the order of the strings being reversed.
I have another issue with authentication, although I assume it applies generally to the encoding of any action response message. I think that if I want to reject an MD5 or SHA1association, by giving an error in the action response message, I need to encode something like:
c7 01 81 fa 00
Where 0xFA is the error code (other reason in this case), and 0x00 says there is no data present. If I do this DLMSDirector says the message is corrupt. If I don't send the final 0x00 DLMSDirector is happy. I might be misinterpreting the requirements, but the following ASN.1 description in the Green Book, seems to indicate that the zero needs to be present to indicate that the optional data field is not present.
Action-Response-With-Optional-Data ::= SEQUENCE
{
result Action-Result,
return-parameters Get-Data-Result OPTIONAL
}
I also have Problems with the GMAC authentication.
I use Version 8.0.0.14 and try to connect to a Elster meter over tcp.
I get a null pointer reference:
__________________________________________________________________________________________________
15:05:46 Initializing Network connection.
System.NullReferenceException: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.
bei GXDLMSDirector.GXDLMSDevice.InitializeConnection() in c:\Code\GXDLMSDirector\Development\GXDLMSDevice.cs:Zeile 386.
bei GXDLMSDirector.MainForm.Connect(Control sender, Object[] parameters) in c:\Code\GXDLMSDirector\Development\MainForm.cs:Zeile 929.
_____________________________________________________________________________________________________
08:06:17 Initializing Network connection.
08:06:17 08:06:17.629 Info Opening
08:06:17 08:06:17.632 Info Client Settings: Protocol Tcp Host: 192.168.9.33 Port: 4059
08:06:17 08:06:17.637 Info Open
A first chance exception of type 'System.NullReferenceException' occurred in Gurux.DLMS.dll
After Line 592 in GXDLMSCommunicator.cs I get a null pointer Exeption
592 ******foreach (byte[] it in AARQRequest())*******
Using DLMSDirector 8.0.0.20 I am having problems with MD5, SHA1 and GMAC authentication. My meter software is happy with the authentication sent my DLMSDirector, but whatever I send back I get "Invalid password. Server to Client challenge do not match". Recently MD5 and SHA1 seemed to be working OK, but they have now stopped in 8.0.0.20. I have never succeeded in authenticating with GMAC, and I might be doing something wrong there - e.g. not having a field set correctly.
It seems the system title for the DLMSDirector software is always ABCDEFGH, and it sends this string in the calling AP title field. My meter is using the system title MMM\0\0\0\0\1, just like the test data in the DLMS specs. I send this title in the responding AP title field of my AARE messages. I have also configured this string in the manufacturer data dialogue for DLMSDirector. I assume I must have the cipher key and authentication key fields set correctly in the manufacturer data, as I get the correct authentication string in the messages from DLMSDirector. Authentication should use the IC field in the StoC and CtoS strings, so that should not require any configuration. I can't think of anything else that I might need to take care to form the correction authentication string to send to DLMSDirector.
The message analysis in 8.0.0.20 treats "81 00 01 00 09..." in the last message as corrupt. If I remove the second 0, which indicates that data is present, the message is treated as correctly structured, and the authentication string is checked. The failure to send or expect the "data present" byte seems to be a common problem in DLMS implementations.
I found another issue with GMAC authentication. If I send an StoC string of up to 14 characters DLMSDirector sends an authentication string which looks OK. If I send a longer StoC string DLMSDirector seems to send an authentication string which is wrong.
HLS
Hi,
I believe you have old version. Get latest version.
BR,
Mikko
HLS
I am using version 7.0.42.1, which is the version currently available for download.
HLS
Hi,
Can you post your trace so we can check it?
You will find it under Tools menu in GXDLMSDirector.
BR,
Mikko
HLS
I realised that I had not set the acse-service-user in my AARE message to 14. This was stopping GXDLMSDirector from proceeding to stages 3 and 4 of the authentication handshake. With this fixed I get an action-request from GXDLMSDirector after I send it an AARE when I use MD5 or SHA1 authentication.
My next problem is the method-invocation-parameters field in the action-request seems wrong. Section 9.2.7.4 of the Green book says that I should feed the challenge string followed by the secret through SHA1 or MD5 to produce the method-invocation-parameters field. However, I can only match the field received from GXDLMSDirector if I pass the secret followed by the challenge string through SHA1 or MD5 (i.e. the reverse order).
When I use GMAC authentication and reply to an AARQ with any kind of AARE message GXDLMSDirector displays an error box saying "Object reference not set to an instance of an object" I tried to debug this, but the open source code on github.com is not up to date, and behaves differently when GMAC is used.
When I use SHA1 or MD5 I can now connect and click read to get the known objects from the meter. However, if I click read a second time I get an error box saying "Specified argument was out of the range of valid values".
HLS
Hi,
This is very common issue. For this reason I asked log file. I'm glad it solved.
You might be correct on this. We was fight with Texas Instruments High Authentication level and it seems that we have broke this.
We will check this later in this week and release new version on end of week.
We will also check source codes in GitHub.
Sorry about this.
BR,
Mikko
HLS
What you call the Texas Instruments high level authentication comes from the India national DLMS spec (i.e. the spec which defines the set of objects which an Indian meter must support). Other people use it too. It was defined before the well defined MD5 and SHA1 authentications were added to the DLMS spec. The Kalkitech Explorer software also supports this, so the TI software is compatible with it. The algorithm is just to use a secret key to AES128 encrypt the challenge string, like so...
/* Encrypt the challenge that was sent to the client */
for (i = 0; i challenge_s2c_len/16; i++)
{
aes128_encrypt(&challenge_s2c[i*16], secret_key);
}
/* Encrypt the challenge that was sent by the client */
for (i = 0; i link->challenge_c2s_len/16; i++)
{
aes128_encrypt(&challenge_c2s[i*16], secret_key);
}
The encrypted challenge_s2c must match the one received from the client.
The encrypted challenge_c2s is sent back to the client.
HLS
I see that the installer for DLMSDirector has been updated to 7.0.43.1, and a few changes have been committed to the git repository. However, high level authentication is still very broken. MD5 and SHA1 authentication only work if the secret and challenge string are processed in the reverse order from the spec. GMAC authentication gives the error "Object reference not set to an instance of an object" because in GXDLMS.cs GXDLMSChipperingStream() is called with "null" for the iv parameter, while in the implementation of GXDLMSChipperingStream() in GXDLMSChipperingStream.cs iv is expected to point to a usable memory address.
HLS
Hi,
We have released new version today.
We have fixed reverse order and HLS issues.
We will fix GMAC issue on next week.
Please, let us know if you still have any problems.
BR,
Mikko
HLS
The authentication in 4.0.75.1 doesn't work at all. I tried the code in the git repo, and with the following changes I can get it to work for the Indian style high level authentication, and MD5 and SHA1 authentication the way the green book defines it. Note that I am not a C# programmer, and the way I got the Indian style authentication to work is a nasty fudge. I assume there is a more elegant way to work step through a long challenge string as it is encrypted.
diff --git a/Development/GXDLMS.cs b/Development/GXDLMS.cs CtoS = new List(Password); CtoS = new List(Password); CtoS = new List(); challenge = new List(Password); challenge = new List();
index 512f013..05c72b2 100644
--- a/Development/GXDLMS.cs
+++ b/Development/GXDLMS.cs
@@ -161,8 +161,10 @@ static public byte[] Chipher(Authentication auth, byte[] challenge, byte[] secre
{
if (auth == Authentication.High)
{
- byte[] p = new byte[challenge.Length];
+ byte[] p = new byte[((challenge.Length + 15)/16)*16];
byte[] s;
+ int i;
+
if (secret.Length 16)
{
s = new byte[16];
@@ -173,8 +175,14 @@ static public byte[] Chipher(Authentication auth, byte[] challenge, byte[] secre
}
challenge.CopyTo(p, 0);
secret.CopyTo(s, 0);
- GXAes128.Encrypt(s, p);
- return s;
+ for (i = 0; i p.Length; i += 16)
+ {
+ byte[] x = new byte[16];
+ Buffer.BlockCopy(p, i, x, 0, 16);
+ GXAes128.Encrypt(x, s);
+ x.CopyTo(p, i);
+ }
+ return p;
}
if (auth == Authentication.HighMD5)
{
@@ -184,7 +192,7 @@ static public byte[] Chipher(Authentication auth, byte[] challenge, byte[] secre
challenge.CopyTo(tmp, 0);
secret.CopyTo(tmp, challenge.Length);
tmp = md5Hash.ComputeHash(tmp);
- Array.Reverse(tmp);
+ //Array.Reverse(tmp);
return tmp;
}
}
@@ -196,7 +204,7 @@ static public byte[] Chipher(Authentication auth, byte[] challenge, byte[] secre
challenge.CopyTo(tmp, 0);
secret.CopyTo(tmp, challenge.Length);
tmp = sha.ComputeHash(tmp);
- Array.Reverse(tmp);
+ //Array.Reverse(tmp);
return tmp;
}
}
diff --git a/Development/GXDLMSClient.cs b/Development/GXDLMSClient.cs
index 17db4dc..18d7005 100644
--- a/Development/GXDLMSClient.cs
+++ b/Development/GXDLMSClient.cs
@@ -816,7 +816,8 @@ public byte[][] GetApplicationAssociationRequest()
{
throw new ArgumentException("Password is invalid.");
}
- List
+ //List
+ List
if (m_Base.StoCChallenge != null)
{
CtoS.AddRange(m_Base.StoCChallenge);
@@ -875,7 +876,7 @@ public void ParseApplicationAssociationResponse(byte[] reply)
throw new Exception("Invalid challenge.");
}
byte[] serverChallenge = (byte[])GXCommon.GetData(arr.ToArray(), ref index, ActionType.None, out total, out read, ref type, ref CacheIndex);
- List
+ List
challenge.AddRange(m_Base.CtoSChallenge);
byte[] clientChallenge = GXDLMS.Chipher(this.Authentication, challenge.ToArray(), Password);
int pos = 0;
HLS
The latest update to the DLMSDirector installer still fails to authenticate. Thanks for bringing the git repository up to date. I was able to find fixes for the Indian mode 2 authentication, MD5, and SHA1. I haven't tried to fix GMAC yet. Apply the following patches to GXCom/Protocols/Gurux.DLMS.Net:
diff --git a/Development/GXDLMS.cs b/Development/GXDLMS.cs CtoS = new List(Password); CtoS = new List(); challenge = new List(Password); challenge = new List();
index 25e8c16..70a49db 100644
--- a/Development/GXDLMS.cs
+++ b/Development/GXDLMS.cs
@@ -161,8 +161,10 @@ static public byte[] Chipher(Authentication auth, byte[] challenge, byte[] secre
{
if (auth == Authentication.High)
{
- byte[] p = new byte[challenge.Length];
+ byte[] p = new byte[((challenge.Length + 15) / 16) * 16];
byte[] s;
+ int i;
+
if (secret.Length 16)
{
s = new byte[16];
@@ -173,8 +175,14 @@ static public byte[] Chipher(Authentication auth, byte[] challenge, byte[] secre
}
challenge.CopyTo(p, 0);
secret.CopyTo(s, 0);
- GXAes128.Encrypt(s, p);
- return s;
+ for (i = 0; i p.Length; i += 16)
+ {
+ byte[] x = new byte[16];
+ Buffer.BlockCopy(p, i, x, 0, 16);
+ GXAes128.Encrypt(x, s);
+ x.CopyTo(p, i);
+ }
+ return p;
}
if (auth == Authentication.HighMD5)
{
diff --git a/Development/GXDLMSClient.cs b/Development/GXDLMSClient.cs
index 1f731b5..a267ba3 100644
--- a/Development/GXDLMSClient.cs
+++ b/Development/GXDLMSClient.cs
@@ -816,7 +816,7 @@ public byte[][] GetApplicationAssociationRequest()
{
throw new ArgumentException("Password is invalid.");
}
- List
+ List
if (m_Base.StoCChallenge != null)
{
CtoS.AddRange(m_Base.StoCChallenge);
@@ -875,7 +875,7 @@ public void ParseApplicationAssociationResponse(byte[] reply)
throw new Exception("Invalid challenge.");
}
byte[] serverChallenge = (byte[])GXCommon.GetData(arr.ToArray(), ref index, ActionType.None, out total, out read, ref type, ref CacheIndex);
- List
+ List
challenge.AddRange(m_Base.CtoSChallenge);
byte[] clientChallenge = GXDLMS.Chipher(this.Authentication, challenge.ToArray(), Password);
int pos = 0;
HLS
Hi,
Thank you very much for your help. We are making some modifications and we will release new version during this month.
BR,
Mikko
HLS
There has been an update to the git code, and the installer says it has been updated to 7.0.48.1, but it hasn't. The installer which can be downloaded is still 7.0.47.1.
The git code still has problems with encrypted authentication. The following diff fixes this:
diff --git a/Development/GXDLMS.cs b/Development/GXDLMS.cs CtoS = new List(Password); CtoS = new List(); challenge = new List(Password); challenge = new List();
index 2fff595..6a87004 100644
--- a/Development/GXDLMS.cs
+++ b/Development/GXDLMS.cs
@@ -161,23 +161,20 @@ static public byte[] Chipher(Authentication auth, byte[] challenge, byte[] secre
{
if (auth == Authentication.High)
{
- byte[] p = new byte[challenge.Length + 15];
- byte[] s = new byte[16];
- byte[] x = new byte[16];
+ byte[] p = new byte[((challenge.Length + 15) / 16) * 16];
+ byte[] s = new byte[(secret.Length 16) ? 16 : secret.Length];
int i;
- if (secret.Length 16)
- {
- challenge.CopyTo(p, 0);
- secret.CopyTo(s, 0);
- for (i = 0; i p.Length; i += 16)
- {
- Buffer.BlockCopy(p, i, x, 0, 16);
- GXAes128.Encrypt(x, s);
- x.CopyTo(p, i);
- }
- return p;
+
+ challenge.CopyTo(p, 0);
+ secret.CopyTo(s, 0);
+ for (i = 0; i p.Length; i += 16)
+ {
+ byte[] x = new byte[16];
+ Buffer.BlockCopy(p, i, x, 0, 16);
+ GXAes128.Encrypt(x, s);
+ x.CopyTo(p, i);
}
- throw new ArgumentException("Chipher failed. Invalid secret.");
+ return p;
}
if (auth == Authentication.HighMD5)
{
diff --git a/Development/GXDLMSClient.cs b/Development/GXDLMSClient.cs
index 046b5e0..78bd857 100644
--- a/Development/GXDLMSClient.cs
+++ b/Development/GXDLMSClient.cs
@@ -816,7 +816,7 @@ public byte[][] GetApplicationAssociationRequest()
{
throw new ArgumentException("Password is invalid.");
}
- List
+ List
if (m_Base.StoCChallenge != null)
{
CtoS.AddRange(m_Base.StoCChallenge);
@@ -875,7 +875,7 @@ public void ParseApplicationAssociationResponse(byte[] reply)
throw new Exception("Invalid challenge.");
}
byte[] serverChallenge = (byte[])GXCommon.GetData(arr.ToArray(), ref index, ActionType.None, out total, out read, ref type, ref CacheIndex);
- List
+ List
challenge.AddRange(m_Base.CtoSChallenge);
byte[] clientChallenge = GXDLMS.Chipher(this.Authentication, challenge.ToArray(), Password);
int pos = 0;
HLS
Hi,
There was some strange thing happened in our Continous Installation system and
new version did not come to our web page. Souce codes was updated to the github as they should be.
Download new version from our web page.
I'm sorry about this.
BR,
Mikko
MD5 and SHA1 authentication
After the major updates between version 7 and 8 of DLMSDirector the code seems to be settling down, but I still have problems with authentication in version 8.0.0.8. If I try to use MD5 authentication over a TCP connection my meter receives the following AARQ message from DLMSDirector:
00 01 00 30 00 01 00 52 60 50 a1 09 06 07 60 85 74 05 08 01 01 8a 02 07 80 8b 07 60 85 74 05 08 02 03 ac 12 80 10 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 be 10 04 0e 01 01 11 52 5f 56 54 53 48 43 70 54 4d 49 66 42 66 41 32 52 00 00 06 5f 1f 04 00 00 7e 1f ff ff
This starts with an 8 byte IEC62056-47 header. The password "aaaaaaaaaaaaaaaa" has been sent as clear text in the calling-authentication-value field, and the user-information field seems completely messed up. When I try SHA1 authentication I get a similar result.
MD5 and SHA1 authentication
Hi,
You are right. We made some changes for GMAC authentication and now we are accidentally send
dedicated key and do not run MD5 or SHA1 for password. We will fix this and release new version during this week.
I'm sorry about this.
BR,
Mikko
MD5 and SHA1 authentication
Hi,
We have fixed this. New version is available on GitHub. We also released new version from GXDLMSDirector.
BR,
Mikko
MD5 and SHA1 authentication
Version 8.0.0.9 gets things a bit farther. However, when I try MD5 or SHA1 authentication, and my meter responds to the AARQ from DLMSDirector with status 14, DLMSDirector says "Object reference set to an instance of an object". An example message exchange is as follows:
AARQ from DLMSDirector:
00 01 00 31 00 01 00 4d 60 4b a1 09 06 07 60 85 74 05 08 01 01 8a 02 07 80 8b 07 60 85 74 05 08 02 04 ac 1f 80 1d 56 62 69 69 27 3e 66 44 64 41 4e 28 59 6a 25 6e 51 33 5f 42 78 69 5a 42 4e 2b 5e 70 34 be 10 04 0e 01 00 00 00 06 5f 1f 04 00 00 10 1d ff ff
AARQ from the meter:
00 01 00 01 00 31 00 4c 61 4a a1 09 06 07 60 85 74 05 08 01 01 a2 03 02 01 00 a3 05 a1 03 02 01 0e 88 02 07 80 89 07 60 85 74 05 08 02 04 aa 12 80 10 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 be 10 04 0e 08 00 06 5f 1f 04 00 00 10 1d 02 00 00 07
MD5 and SHA1 authentication
Hi,
We did try to duplicate this with your trace. We are receiving "Invalid password" exception.
Have you modify the source code?
BR,
Mikko
MD5 and SHA1 authentication
I did not use the source code. I just installed DLMSDirector 8.0.0.9 Windows installer and used it to communicate with my meter.
MD5 and SHA1 authentication
Hi,
We have installed new version to several Windows versions and every time we get "Password is invalid" -message.
Can you try to uninstall existing version(s) and then install new version from GXDLMSDirector. I hope that helps.
BR,
Mikko
MD5 and SHA1 authentication
When I tried uninstalling 8.0.0.9 I found the Windows control panel "Programs and Features" page list several earlier versions of DLMSDirector, as well as 8.0.0.9. It seems the update process in DLMSDirector isn't clearing out older versions during update. I removed all the versions I could find, and reinstalled 8.0.0.9. I still get the same result, as follows, for an attempt to use MD5 authentication:
4:25:53 PM Initializing Network connection.
4:25:54 PM Send AARQ request
00 01 00 30 00 01 00 5A 60 58 A1 09 06 07 60 85 74 05 08 01 01 8A 02 07 80 8B 07 60 85 74 05 08 02 03 AC 2C 80 2A 56 47 35 27 4E 4E 22 6D 75 57 56 58 3A 22 44 71 43 4F 3A 62 61 5C 4A 6A 27 47 33 6F 59 42 63 5B 44 46 6A 41 22 51 52 41 36 61 BE 10 04 0E 01 00 00 00 06 5F 1F 04 00 00 7E 1F FF FF
4:25:54 PM Received data
00 01 00 01 00 30 00 4C 61 4A A1 09 06 07 60 85 74 05 08 01 01 A2 03 02 01 00 A3 05 A1 03 02 01 0E 88 02 07 80 89 07 60 85 74 05 08 02 03 AA 12 80 10 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 BE 10 04 0E 08 00 06 5F 1F 04 00 00 10 1D 02 00 00 07
4:25:54 PM Parsing AARE reply<CR><LF>61 4A A1 09 06 07 60 85 74 05 08 01 01 A2 03 02 01 00 A3 05 A1 03 02 01 0E 88 02 07 80 89 07 60 85 74 05 08 02 03 AA 12 80 10 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 BE 10 04 0E 08 00 06 5F 1F 04 00 00 10 1D 02 00 00 07
System.NullReferenceException: Object reference not set to an instance of an object.
at GXDLMSDirector.GXDLMSDevice.InitializeConnection() in C:\Projects\GXDLMSDirector\Development\GXDLMSDevice.cs:line 374
at GXDLMSDirector.MainForm.Connect(Control sender, Object[] parameters) in C:\Projects\GXDLMSDirector\Development\MainForm.cs:line 929
Object reference not set to an instance of an object
Hi,
Finally we was able to duplicate your error. We will fix it and release new version on Friday.
BR,
Mikko
MD5 and SHA1 authentication
Version 8.0.0.12 of DLMSDirector fixes the problems I was experiencing with 8.0.0.9, but now I find a similar problem to one I reported earlier. The Green Book says the way to calculate the SHA1 authentication values is SHA-1(StoC || HLS Secret) and SHA-1(CtoS || HLS Secret). DLMSDirector seems to be applying the strings to the SHA-1 algorithm in the reverse order, i.e. SHA-1(HLS Secret || StoC) and SHA-1(HLS Secret || CtoS). If I modify my meter code to use the order the DLMSDirector is using, the authentication steps work. MD5 shows this same issue, of the order of the strings being reversed.
MD5 and SHA1 authentication
Hi,
I checked this from Blue book and you are right. We changed the order and release new version today.
BR,
Mikko
MD5 and SHA1authentication
I have another issue with authentication, although I assume it applies generally to the encoding of any action response message. I think that if I want to reject an MD5 or SHA1association, by giving an error in the action response message, I need to encode something like:
c7 01 81 fa 00
Where 0xFA is the error code (other reason in this case), and 0x00 says there is no data present. If I do this DLMSDirector says the message is corrupt. If I don't send the final 0x00 DLMSDirector is happy. I might be misinterpreting the requirements, but the following ASN.1 description in the Green Book, seems to indicate that the zero needs to be present to indicate that the optional data field is not present.
Action-Response-With-Optional-Data ::= SEQUENCE
{
result Action-Result,
return-parameters Get-Data-Result OPTIONAL
}
MD5 and SHA1authentication
Hi,
We fixed that CtoS and secret issue:
http://www.gurux.fi/node/4901
You are right, Meters that we are using for testing are not returning anything after Action-Result, if there is no data. We will fix this.
BR,
Mikko
HIGH GMAC
I also have Problems with the GMAC authentication.
I use Version 8.0.0.14 and try to connect to a Elster meter over tcp.
I get a null pointer reference:
__________________________________________________________________________________________________
15:05:46 Initializing Network connection.
System.NullReferenceException: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.
bei GXDLMSDirector.GXDLMSDevice.InitializeConnection() in c:\Code\GXDLMSDirector\Development\GXDLMSDevice.cs:Zeile 386.
bei GXDLMSDirector.MainForm.Connect(Control sender, Object[] parameters) in c:\Code\GXDLMSDirector\Development\MainForm.cs:Zeile 929.
_____________________________________________________________________________________________________
Kind Regards,
Marco
HIGH GMAC
Hi Marco,
Are you using secured connection or just GMAC?
We will check this on Friday.
BR,
Mikko
HIGH GMAC
I use GMAC authetication:
Global Encryption key: 0001020304XXXXXXXXXXXXXXXXXX
Authenthication key: D0D1D2DXXXXXXXXXXXXXXXXXXXX
Ciphering: None
Thanks for your help
HIGH GMAC
I use GMAC authetication:
Global Encryption key: 0001020304XXXXXXXXXXXXXXXXXX
Authenthication key: D0D1D2DXXXXXXXXXXXXXXXXXXXX
Ciphering: None
Thanks for your help
High GMAC
08:06:17 Initializing Network connection.
08:06:17 08:06:17.629 Info Opening
08:06:17 08:06:17.632 Info Client Settings: Protocol Tcp Host: 192.168.9.33 Port: 4059
08:06:17 08:06:17.637 Info Open
A first chance exception of type 'System.NullReferenceException' occurred in Gurux.DLMS.dll
After Line 592 in GXDLMSCommunicator.cs I get a null pointer Exeption
592 ******foreach (byte[] it in AARQRequest())*******
High GMAC
Hi Marco,
I just update answer here because we are receiving a lot of emails is this fixed.
This is fixed and GMAC authentication is working.
BR,
Mikko
MD5, SHA1 and GMAC authentication problems
Using DLMSDirector 8.0.0.20 I am having problems with MD5, SHA1 and GMAC authentication. My meter software is happy with the authentication sent my DLMSDirector, but whatever I send back I get "Invalid password. Server to Client challenge do not match". Recently MD5 and SHA1 seemed to be working OK, but they have now stopped in 8.0.0.20. I have never succeeded in authenticating with GMAC, and I might be doing something wrong there - e.g. not having a field set correctly.
It seems the system title for the DLMSDirector software is always ABCDEFGH, and it sends this string in the calling AP title field. My meter is using the system title MMM\0\0\0\0\1, just like the test data in the DLMS specs. I send this title in the responding AP title field of my AARE messages. I have also configured this string in the manufacturer data dialogue for DLMSDirector. I assume I must have the cipher key and authentication key fields set correctly in the manufacturer data, as I get the correct authentication string in the messages from DLMSDirector. Authentication should use the IC field in the StoC and CtoS strings, so that should not require any configuration. I can't think of anything else that I might need to take care to form the correction authentication string to send to DLMSDirector.
Authentication message analysis appears broken in 8.0.0.20
Looking at this a bit more it looks like the message analysis in DLMSDirector has been broken. If my authentication sequence is:
12:28:12 AM Send AARQ request
00 01 00 30 00 01 00 40 60 3E A1 09 06 07 60 85 74 05 08 01 01 8A 02 07 80 8B 07 60 85 74 05 08 02 03 AC 12 80 10 71 2F 65 3B 64 49 56 35 27 25 67 3D 2B 5C 3A 49 BE 10 04 0E 01 00 00 00 06 5F 1F 04 00 00 10 1D FF FF
12:28:12 AM Received data
00 01 00 01 00 30 00 44 61 42 A1 09 06 07 60 85 74 05 08 01 01 A2 03 02 01 00 A3 05 A1 03 02 01 0E 88 02 07 80 89 07 60 85 74 05 08 02 03 AA 0A 80 08 50 36 77 52 4A 32 31 46 BE 10 04 0E 08 00 06 5F 1F 04 00 00 10 1D 02 00 00 07
12:28:12 AM Parsing AARE reply<CR><LF>61 42 A1 09 06 07 60 85 74 05 08 01 01 A2 03 02 01 00 A3 05 A1 03 02 01 0E 88 02 07 80 89 07 60 85 74 05 08 02 03 AA 0A 80 08 50 36 77 52 4A 32 31 46 BE 10 04 0E 08 00 06 5F 1F 04 00 00 10 1D 02 00 00 07
Authentication is required.
- Server max PDU size is 512
12:28:12 AM Authenticating
00 01 00 30 00 01 00 1F C3 01 81 00 0F 00 00 28 00 00 FF 01 01 09 10 64 9F 58 89 83 81 A6 C4 84 D9 96 3D C4 A4 33 C2
12:28:12 AM Received data
00 01 00 01 00 30 00 18 C7 01 81 00 01 00 09 10 6F 55 24 03 DC D9 CF 24 CF 7A A1 0C 25 6F 1D 25
The message analysis in 8.0.0.20 treats "81 00 01 00 09..." in the last message as corrupt. If I remove the second 0, which indicates that data is present, the message is treated as correctly structured, and the authentication string is checked. The failure to send or expect the "data present" byte seems to be a common problem in DLMS implementations.
Authentication message analysis appears broken in 8.0.0.20
I found another issue with GMAC authentication. If I send an StoC string of up to 14 characters DLMSDirector sends an authentication string which looks OK. If I send a longer StoC string DLMSDirector seems to send an authentication string which is wrong.