diff --git a/src/JT809.Protocol.Test/JT809Encrypt/JT809EncryptTest.cs b/src/JT809.Protocol.Test/JT809Encrypt/JT809EncryptTest.cs index 767be5d..5151ec5 100644 --- a/src/JT809.Protocol.Test/JT809Encrypt/JT809EncryptTest.cs +++ b/src/JT809.Protocol.Test/JT809Encrypt/JT809EncryptTest.cs @@ -14,8 +14,7 @@ namespace JT809.Protocol.Test.JT809Encrypt { IA1 = 20000000, IC1 = 20000000, - M1 = 30000000, - Key = 256178, + M1 = 30000000 }; [Fact] @@ -26,7 +25,7 @@ namespace JT809.Protocol.Test.JT809Encrypt 01,02,03,04,05,06,07 }; IJT809Encrypt jT809Encrypt = new JT809EncryptImpl(options); - var data = jT809Encrypt.Encrypt(bytes).ToHexString(); + var data = jT809Encrypt.Encrypt(bytes, 256178).ToHexString(); //"D3 4C 70 78 A7 3A 41" } @@ -35,7 +34,7 @@ namespace JT809.Protocol.Test.JT809Encrypt { byte[] bytes = "D3 4C 70 78 A7 3A 41".ToHexBytes(); IJT809Encrypt jT809Encrypt = new JT809EncryptImpl(options); - var data = jT809Encrypt.Decrypt(bytes); + var data = jT809Encrypt.Decrypt(bytes, 256178); Assert.Equal(new byte[] { 01,02,03,04,05,06,07 diff --git a/src/JT809.Protocol.Test/JT809HeaderTest.cs b/src/JT809.Protocol.Test/JT809HeaderTest.cs index 3c4926e..e5b943c 100644 --- a/src/JT809.Protocol.Test/JT809HeaderTest.cs +++ b/src/JT809.Protocol.Test/JT809HeaderTest.cs @@ -53,5 +53,19 @@ namespace JT809.Protocol.Test }); var sn = JT809GlobalConfig.Instance.MsgSNDistributed.Increment(); } + + [Fact] + public void Test4() + { + JT809Header jT809Header = new JT809Header(); + jT809Header.MsgLength = 24; + jT809Header.MsgSN = 1024; + jT809Header.BusinessType = JT809Enums.JT809BusinessType.从链路静态信息交换消息; + jT809Header.MsgGNSSCENTERID = 1200; + jT809Header.Version = new JT809Header_Version (0xFF,0xAA,0xBB); + jT809Header.EncryptFlag = JT809Header_Encrypt.None; + jT809Header.EncryptKey = 0; + var hex = JT809Serializer.Serialize(jT809Header).ToHexString(); + } } } diff --git a/src/JT809.Protocol.Test/JT809Packages/JT809_0x1001EncryptPackageTest.cs b/src/JT809.Protocol.Test/JT809Packages/JT809_0x1001EncryptPackageTest.cs index 62b2ecc..fcb6447 100644 --- a/src/JT809.Protocol.Test/JT809Packages/JT809_0x1001EncryptPackageTest.cs +++ b/src/JT809.Protocol.Test/JT809Packages/JT809_0x1001EncryptPackageTest.cs @@ -17,8 +17,7 @@ namespace JT809.Protocol.Test.JT809Packages { IA1 = 20000000, IC1 = 20000000, - M1 = 30000000, - Key = 256178, + M1 = 30000000 })); } @@ -28,11 +27,11 @@ namespace JT809.Protocol.Test.JT809Packages JT809Package jT809Package = new JT809Package(); jT809Package.Header = new JT809Header { - EncryptFlag= JT809Header_Encrypt.Common, - MsgSN= 133, - EncryptKey=5819, - BusinessType= JT809Enums.JT809BusinessType.主链路登录请求消息, - MsgGNSSCENTERID= 20180920, + EncryptFlag = JT809Header_Encrypt.Common, + MsgSN = 133, + EncryptKey = 256178, + BusinessType = JT809Enums.JT809BusinessType.主链路登录请求消息, + MsgGNSSCENTERID = 20180920, }; JT809_0x1001 jT809_0X1001 = new JT809_0x1001(); jT809_0X1001.UserId = 20180920; @@ -47,16 +46,15 @@ namespace JT809.Protocol.Test.JT809Packages [Fact] public void Test2() { - var bytes = "5B 00 00 00 48 00 00 00 85 10 01 01 33 EF B8 01 00 00 01 00 00 16 BB D3 7D 9C C4 90 0C 77 DC 78 F8 67 65 27 D8 AE 12 24 3C FB 64 CC 2F BA 61 9A EF AD 33 AC CB 32 56 F6 7B FF 19 DF 33 09 78 41 09 86 65 70 3F 2E B5 5D".ToHexBytes(); + var bytes = "5B000000480000008510010133EFB8010000010003E8B2D37D9CC4900C77DC78F8676527D8AE12243CFB64CC2FBA619AEFAD33ACCB3256F67BFF19DF33097841098665703FE36E5D".ToHexBytes(); JT809Package jT809Package = JT809Serializer.Deserialize(bytes); Assert.Equal(JT809Header_Encrypt.Common, jT809Package.Header.EncryptFlag); - Assert.Equal((uint)5819, jT809Package.Header.EncryptKey); + Assert.Equal((uint)256178, jT809Package.Header.EncryptKey); Assert.Equal((uint)72, jT809Package.Header.MsgLength); Assert.Equal((uint)133, jT809Package.Header.MsgSN); - Assert.Equal((uint)5819, jT809Package.Header.EncryptKey); Assert.Equal((uint)20180920, jT809Package.Header.MsgGNSSCENTERID); Assert.Equal(JT809Enums.JT809BusinessType.主链路登录请求消息, jT809Package.Header.BusinessType); - Assert.Equal(new JT809Header_Version().ToString(), jT809Package.Header.Version.ToString()); + Assert.Equal("1.0.0", jT809Package.Header.Version.ToString()); JT809_0x1001 jT809_0X1001 = (JT809_0x1001)jT809Package.Bodies; Assert.Equal((uint)20180920, jT809_0X1001.UserId); Assert.Equal("20180920", jT809_0X1001.Password); diff --git a/src/JT809.Protocol/IJT809Encrypt.cs b/src/JT809.Protocol/IJT809Encrypt.cs index f1d497a..8fc4396 100644 --- a/src/JT809.Protocol/IJT809Encrypt.cs +++ b/src/JT809.Protocol/IJT809Encrypt.cs @@ -2,7 +2,7 @@ { public interface IJT809Encrypt { - byte[] Encrypt(byte[] buffer); - byte[] Decrypt(byte[] buffer); + byte[] Encrypt(byte[] buffer, uint privateKey); + byte[] Decrypt(byte[] buffer, uint privateKey); } } diff --git a/src/JT809.Protocol/JT809Configs/JT809EncryptOptions.cs b/src/JT809.Protocol/JT809Configs/JT809EncryptOptions.cs index bc0f216..e00bc99 100644 --- a/src/JT809.Protocol/JT809Configs/JT809EncryptOptions.cs +++ b/src/JT809.Protocol/JT809Configs/JT809EncryptOptions.cs @@ -5,6 +5,5 @@ public uint M1 { get; set; } public uint IA1 { get; set; } public uint IC1 { get; set; } - public uint Key { get; set; } } } diff --git a/src/JT809.Protocol/JT809Encrypt/JT809EncryptImpl.cs b/src/JT809.Protocol/JT809Encrypt/JT809EncryptImpl.cs index 4c1e8e7..79e2e49 100644 --- a/src/JT809.Protocol/JT809Encrypt/JT809EncryptImpl.cs +++ b/src/JT809.Protocol/JT809Encrypt/JT809EncryptImpl.cs @@ -14,17 +14,17 @@ namespace JT809.Protocol.JT809Encrypt this.jT809EncryptOptions = jT809EncryptOptions; } - public byte[] Decrypt(byte[] buffer) + public byte[] Decrypt(byte[] buffer, uint privateKey) { - return Encrypt(buffer); + return Encrypt(buffer, privateKey); } - public byte[] Encrypt(byte[] buffer) + public byte[] Encrypt(byte[] buffer, uint privateKey) { byte[] data = new byte[buffer.Length]; - if (0 == jT809EncryptOptions.Key) + if (0 == privateKey) { - jT809EncryptOptions.Key = 1; + privateKey = 1; } uint mkey = jT809EncryptOptions.M1; if (0 == mkey) @@ -33,8 +33,8 @@ namespace JT809.Protocol.JT809Encrypt } for (int idx = 0; idx < buffer.Length; idx++) { - jT809EncryptOptions.Key = jT809EncryptOptions.IA1 * (jT809EncryptOptions.Key % mkey) + jT809EncryptOptions.IC1; - buffer[idx] ^= (byte)((jT809EncryptOptions.Key >> 20) & 0xFF); + privateKey = jT809EncryptOptions.IA1 * (privateKey % mkey) + jT809EncryptOptions.IC1; + buffer[idx] ^= (byte)((privateKey >> 20) & 0xFF); data[idx] = buffer[idx]; } return data; diff --git a/src/JT809.Protocol/JT809Extensions/JT809BCDExtensions.cs b/src/JT809.Protocol/JT809Extensions/JT809BCDExtensions.cs index b616839..9013f31 100644 --- a/src/JT809.Protocol/JT809Extensions/JT809BCDExtensions.cs +++ b/src/JT809.Protocol/JT809Extensions/JT809BCDExtensions.cs @@ -19,14 +19,24 @@ namespace JT809.Protocol.JT809Extensions return bcdSb.ToString(); } - public static int WriteBCDLittle(IMemoryOwner memoryOwner, int offset, string data, int digit, int len) + public static int WriteBCDLittle(IMemoryOwner memoryOwner, int offset, string data,int len) { - ReadOnlySpan bcd = data.PadLeft(len, '0').AsSpan(); - for (int i = 0; i < digit; i++) + string bcdText = data == null ? "" : data; + byte[] bytes = new byte[len]; + int startIndex = 0; + int noOfZero = len * 2 - bcdText.Length; + if (noOfZero > 0) { - memoryOwner.Memory.Span[offset + i] = Convert.ToByte(bcd.Slice(i * 2, 2).ToString(), 16); + bcdText = bcdText.Insert(startIndex, new string('0', noOfZero)); } - return digit; + int byteIndex = 0; + while (startIndex < bcdText.Length && byteIndex < len) + { + memoryOwner.Memory.Span[startIndex + offset] = Convert.ToByte(bcdText.Substring(startIndex, 2), 16); + startIndex += 2; + byteIndex++; + } + return len; } } } diff --git a/src/JT809.Protocol/JT809Extensions/JT809HexExtensions.cs b/src/JT809.Protocol/JT809Extensions/JT809HexExtensions.cs index fe93e2c..482f60c 100644 --- a/src/JT809.Protocol/JT809Extensions/JT809HexExtensions.cs +++ b/src/JT809.Protocol/JT809Extensions/JT809HexExtensions.cs @@ -118,27 +118,9 @@ namespace JT809.Protocol.JT809Extensions /// /// /// - public static byte[] ToHexBytes(this string hexString, string separator = " ") + public static byte[] ToHexBytes(this string hexString) { - return hexString.Split(new string[] { separator }, StringSplitOptions.RemoveEmptyEntries).Select(s => Convert.ToByte(s, 16)).ToArray(); - } - - /// - /// 16进制字符串转16进制数组 - /// - /// - /// - public static byte[] ToStr2HexBytes(this string hexString) - { - //byte[] buf = new byte[hexString.Length / 2]; - //for (int i = 0; i < hexString.Length; i++) - //{ - // if (i % 2 == 0) - // { - // buf[i / 2] = Convert.ToByte(hexString.Substring(i, 2), 16) ; - // } - - //} + hexString = hexString.Replace(" ", ""); byte[] buf = new byte[hexString.Length / 2]; ReadOnlySpan readOnlySpan = hexString.AsSpan(); for (int i = 0; i < hexString.Length; i++) @@ -149,13 +131,6 @@ namespace JT809.Protocol.JT809Extensions } } return buf; - //List bytes = new List(); - //while (hexString.Length>0) - //{ - // bytes.Add(Convert.ToByte(hexString.AsSpan(0, 2).ToString(), 16)); - // hexString = hexString.Remove(0,2); - //} - //return Regex.Replace(hexString, @"(\w{2})", "$1 ").Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries).Select(s => Convert.ToByte(s, 16)).ToArray(); } public unsafe static string ReadHexStringLittle(ReadOnlySpan read, ref int offset, int len) diff --git a/src/JT809.Protocol/JT809Formatters/JT809PackageFormatter.cs b/src/JT809.Protocol/JT809Formatters/JT809PackageFormatter.cs index b89e0e3..83b2dc1 100644 --- a/src/JT809.Protocol/JT809Formatters/JT809PackageFormatter.cs +++ b/src/JT809.Protocol/JT809Formatters/JT809PackageFormatter.cs @@ -65,7 +65,7 @@ namespace JT809.Protocol.JT809Formatters jT809Package.Bodies = JT809FormatterResolverExtensions.JT809DynamicDeserialize(JT809FormatterExtensions.GetFormatter(jT809BodiesTypeAttribute.JT809BodiesType), buffer.Slice(offset, checkIndex - offset), out readSize); break; case JT809Header_Encrypt.Common: - byte[] bodiesData = JT809GlobalConfig.Instance.Encrypt.Decrypt(buffer.Slice(offset, checkIndex - offset).ToArray()); + byte[] bodiesData = JT809GlobalConfig.Instance.Encrypt.Decrypt(buffer.Slice(offset, checkIndex - offset).ToArray(), jT809Package.Header.EncryptKey); jT809Package.Bodies = JT809FormatterResolverExtensions.JT809DynamicDeserialize(JT809FormatterExtensions.GetFormatter(jT809BodiesTypeAttribute.JT809BodiesType), bodiesData, out readSize); break; } @@ -104,7 +104,7 @@ namespace JT809.Protocol.JT809Formatters case JT809Header_Encrypt.None: break; case JT809Header_Encrypt.Common: - messageBodyData = JT809GlobalConfig.Instance.Encrypt.Encrypt(messageBodyData); + messageBodyData = JT809GlobalConfig.Instance.Encrypt.Encrypt(messageBodyData, value.Header.EncryptKey); break; } } diff --git a/src/JT809.Protocol/JT809Formatters/JT809SubMessageBodyFormatters/JT809_0x9500_0x9505Formatter.cs b/src/JT809.Protocol/JT809Formatters/JT809SubMessageBodyFormatters/JT809_0x9500_0x9505Formatter.cs index 9604eb2..7ffab0c 100644 --- a/src/JT809.Protocol/JT809Formatters/JT809SubMessageBodyFormatters/JT809_0x9500_0x9505Formatter.cs +++ b/src/JT809.Protocol/JT809Formatters/JT809SubMessageBodyFormatters/JT809_0x9500_0x9505Formatter.cs @@ -27,7 +27,7 @@ namespace JT809.Protocol.JT809Formatters.JT809SubMessageBodyFormatters public int Serialize(IMemoryOwner memoryOwner, int offset, JT809_0x9500_0x9505 value) { - offset += JT809BinaryExtensions.WriteBCDLittle(memoryOwner, offset, value.AuthenticationCode,10,20); + offset += JT809BinaryExtensions.WriteBCDLittle(memoryOwner, offset, value.AuthenticationCode,20); offset += JT809BinaryExtensions.WriteStringLittle(memoryOwner, offset, value.AccessPointName,20); offset += JT809BinaryExtensions.WriteStringLittle(memoryOwner, offset, value.UserName, 49); offset += JT809BinaryExtensions.WriteStringLittle(memoryOwner, offset, value.Password, 22); diff --git a/src/JT809.Protocol/JT809GlobalConfig.cs b/src/JT809.Protocol/JT809GlobalConfig.cs index d772d0d..ea7e2fc 100644 --- a/src/JT809.Protocol/JT809GlobalConfig.cs +++ b/src/JT809.Protocol/JT809GlobalConfig.cs @@ -1,4 +1,5 @@ using JT809.Protocol.JT809Configs; +using JT809.Protocol.JT809Encrypt; using JT809.Protocol.JT809Internal; using System; using System.Collections.Generic; @@ -27,7 +28,9 @@ namespace JT809.Protocol public IJT809Encrypt Encrypt { get; private set; } - public IMsgSNDistributed MsgSNDistributed {get;private set;} + public JT809EncryptOptions EncryptOptions { get; private set; } + + public IMsgSNDistributed MsgSNDistributed { get; private set; } public JT809HeaderOptions HeaderOptions { get; private set; } /// @@ -36,6 +39,19 @@ namespace JT809.Protocol /// public bool SkipCRCCode { get; private set; } /// + /// 设置加密算法选项值 + /// 不同的上下级平台之间,加密的算法是一致的,但是针对 M1, IA1, IC1 的不同。 + /// 数据先经过加密而后解密。 + /// + /// + /// + public JT809GlobalConfig SetEncryptOptions(JT809EncryptOptions jT809EncryptOptions) + { + instance.Value.Encrypt = new JT809EncryptImpl(jT809EncryptOptions); + instance.Value.EncryptOptions = jT809EncryptOptions; + return instance.Value; + } + /// /// 设置加密算法实现 /// /// diff --git a/src/JT809.Protocol/JT809Header.cs b/src/JT809.Protocol/JT809Header.cs index 7defbc8..519ab26 100644 --- a/src/JT809.Protocol/JT809Header.cs +++ b/src/JT809.Protocol/JT809Header.cs @@ -38,6 +38,7 @@ namespace JT809.Protocol /// 协议版本号标识,上下级平台之间采用的标准协议版 /// 编号;长度为 3 个字节来表示,0x01 0x02 0x0F 标识 /// 的版本号是 v1.2.15,以此类推。 + /// Hex编码 /// public JT809Header_Version Version { get; set; } = new JT809Header_Version(); /// diff --git a/src/JT809.Protocol/JT809Header_Version.cs b/src/JT809.Protocol/JT809Header_Version.cs index f7958f5..3198ca5 100644 --- a/src/JT809.Protocol/JT809Header_Version.cs +++ b/src/JT809.Protocol/JT809Header_Version.cs @@ -4,6 +4,10 @@ using System.Text; namespace JT809.Protocol { + /// + /// 协议版本号标识 + /// Hex编码 + /// public class JT809Header_Version { public byte[] Buffer { get; } = new byte[3]; @@ -32,6 +36,7 @@ namespace JT809.Protocol /// /// 默认1.0.0版本 + /// Hex编码 /// public JT809Header_Version() { @@ -39,14 +44,22 @@ namespace JT809.Protocol Minor = 0; Build = 0; } - + /// + /// + /// + /// 0x00~0xFF + /// 0x00~0xFF + /// 0x00~0xFF public JT809Header_Version(byte major, byte minor, byte buid) { Major = major; Minor = minor; Build = buid; } - + /// + /// + /// + /// [0x00~0xFF,0x00~0xFF,0x00~0xFF] public JT809Header_Version(byte[] bytes) { Major = bytes[0];