14 private byte[] _securityKey = DefaultKey;
19 internal static readonly
byte[] DefaultKey =
"0123456789:;<=>?"u8.ToArray();
34 public void Reset(
byte[] securityKey =
null)
36 if (securityKey !=
null)
38 _securityKey = securityKey;
41 IsUsingDefaultKey = !(_securityKey !=
null && !_securityKey.SequenceEqual(DefaultKey));
43 IsSecurityEstablished =
false;
44 new Random().NextBytes(ServerRandomNumber);
58 internal void UpdateSecurityKey(
byte[] securityKey)
60 if (securityKey ==
null)
65 _securityKey = securityKey;
72 internal bool IsSecurityEstablished {
get;
set; }
77 internal byte[] Enc {
get;
set; } = Array.Empty<
byte>();
82 internal byte[] SMac1 {
get;
set; } = Array.Empty<
byte>();
87 internal byte[] SMac2 {
get;
set; } = Array.Empty<
byte>();
92 internal byte[] RMac {
get;
set; } = Array.Empty<
byte>();
97 internal byte[] CMac {
get;
set; } = Array.Empty<
byte>();
102 internal byte[] ServerCryptogram {
get;
private set; }
114 internal byte[] ServerRandomNumber {
get; } =
new byte[8];
146 internal Aes CreateCypher(
bool isForSessionSetup,
byte[] key =
null)
148 var crypto = Aes.Create();
151 throw new Exception(
"Unable to create AES algorithm");
154 if (!isForSessionSetup)
156 crypto.Mode = CipherMode.CBC;
157 crypto.Padding = PaddingMode.None;
161 crypto.Mode = CipherMode.ECB;
162 crypto.Padding = PaddingMode.Zeros;
165 crypto.KeySize = 128;
166 crypto.BlockSize = 128;
167 crypto.Key = key ?? _securityKey;
179 internal static byte[] GenerateKey(Aes aes,
byte[] input)
181 var buffer =
new byte[16];
182 input.CopyTo(buffer, 0);
184 using var encryptor = aes.CreateEncryptor();
185 return encryptor.TransformFinalBlock(buffer, 0, buffer.Length);
197 internal static byte[] GenerateKey(Aes aes,
byte[] input1,
byte[] input2)
199 var buffer =
new byte[16];
200 input1.CopyTo(buffer, 0);
201 input2.CopyTo(buffer, input1.Length);
203 using var encryptor = aes.CreateEncryptor();
204 return encryptor.TransformFinalBlock(buffer, 0, buffer.Length);
213 internal void InitializeACU(
byte[] clientRandomNumber,
byte[] clientCryptogram)
215 using var keyAlgorithm = CreateCypher(
true);
216 Enc = GenerateKey(keyAlgorithm,
new byte[]
218 0x01, 0x82, ServerRandomNumber[0], ServerRandomNumber[1], ServerRandomNumber[2],
219 ServerRandomNumber[3], ServerRandomNumber[4], ServerRandomNumber[5]
222 using var serverCypher = CreateCypher(
true, Enc);
223 if (!clientCryptogram.SequenceEqual(GenerateKey(serverCypher,
224 ServerRandomNumber, clientRandomNumber)))
226 throw new Exception(
"Invalid client cryptogram");
229 SMac1 = GenerateKey(keyAlgorithm,
232 0x01, 0x01, ServerRandomNumber[0], ServerRandomNumber[1], ServerRandomNumber[2],
233 ServerRandomNumber[3], ServerRandomNumber[4], ServerRandomNumber[5]
235 SMac2 = GenerateKey(keyAlgorithm,
238 0x01, 0x02, ServerRandomNumber[0], ServerRandomNumber[1], ServerRandomNumber[2],
239 ServerRandomNumber[3], ServerRandomNumber[4], ServerRandomNumber[5]
242 ServerCryptogram = GenerateKey(serverCypher, clientRandomNumber, ServerRandomNumber);
246 internal void Establish(
byte[] rmac)
249 IsSecurityEstablished =
true;
bool IsUsingDefaultKey
Gets a value indicating whether the security context is using the default key.
void Reset(byte[] securityKey=null)
Resets secure channel back to its initial state.
bool IsInitialized
Gets a value indicating whether the security context is initialized.
SecurityContext(byte[] securityKey=null)
Represents a security context for OSDP secure channel.