public async Task PutKeyAsync(DaplugKeySet key, byte mode = 0x81) { var putKeyCommandAPDUBytes = new List <byte> { 0x80, 0xD8, key.Version, mode, 0x00 }; //header // Key version putKeyCommandAPDUBytes.Add(key.Version); //Add the keys to the command data var encKeyData = PrepareKeyToPutKeyCommand(key.EncKey, (byte)key.Usage, key.Access); putKeyCommandAPDUBytes.AddRange(encKeyData); var macKeyData = PrepareKeyToPutKeyCommand(key.MacKey, (byte)key.Usage, key.Access); putKeyCommandAPDUBytes.AddRange(macKeyData); var keKeyData = PrepareKeyToPutKeyCommand(key.DeKey, (byte)key.Usage, key.Access); putKeyCommandAPDUBytes.AddRange(keKeyData); var putKeyCommand = new APDUCommand(putKeyCommandAPDUBytes.ToArray()); var response = await ExchangeAPDUAsync(putKeyCommand); if (!response.IsSuccessfulResponse) { throw new DaplugAPIException("Error: " + response.SW1 + response.SW2); } }
public static DaplugSessionKeys ComputeSessionKeys(DaplugKeySet keyset, byte[] seqCounter) { byte[] dataToEncrypt = new byte[16]; Array.Copy(seqCounter, 0, dataToEncrypt, 2, 2); byte[] SEncBytes = new byte[2] { 0x01, 0x82 }; byte[] REncBytes = new byte[2] { 0x01, 0x83 }; byte[] CMacEncBytes = new byte[2] { 0x01, 0x01 }; byte[] RMacEncBytes = new byte[2] { 0x01, 0x02 }; byte[] SKekEncBytes = new byte[2] { 0x01, 0x81 }; DaplugSessionKeys sessionKeys = new DaplugSessionKeys(); Array.Copy(SEncBytes, 0, dataToEncrypt, 0, 2); sessionKeys.SEncKey = Crypto.TripleDESEncrypt(keyset.EncKey, dataToEncrypt); Array.Copy(REncBytes, 0, dataToEncrypt, 0, 2); sessionKeys.REncKey = Crypto.TripleDESEncrypt(keyset.EncKey, dataToEncrypt); Array.Copy(CMacEncBytes, 0, dataToEncrypt, 0, 2); sessionKeys.CMacKey = Crypto.TripleDESEncrypt(keyset.MacKey, dataToEncrypt); Array.Copy(RMacEncBytes, 0, dataToEncrypt, 0, 2); sessionKeys.RMacKey = Crypto.TripleDESEncrypt(keyset.MacKey, dataToEncrypt); Array.Copy(SKekEncBytes, 0, dataToEncrypt, 0, 2); sessionKeys.SKEKey = Crypto.TripleDESEncrypt(keyset.DeKey, dataToEncrypt); return(sessionKeys); }
public async Task OpenSecureChannelAsync(DaplugKeySet keyset, DaplugSecurityLevel securityLevel, byte[] diversifier = null, byte[] hostChallenge = null) { if (keyset.EncKey == null || keyset.MacKey == null || keyset.DeKey == null) { throw new DaplugAPIException("Invalid keyset."); } if (hostChallenge == null) { Random rnd = new Random(); hostChallenge = new byte[8]; rnd.NextBytes(hostChallenge); } var authCommandHeader = new byte[] { 0x80, 0x50, keyset.Version, 0x00, 0x00 }; var authCommand = new APDUCommand(authCommandHeader, hostChallenge); var response = await ExchangeAPDUAsync(authCommand); if (response.IsSuccessfulResponse == false) { throw new DaplugAPIException("INITIALIZE UPDATE failed.", response.SW1, response.SW2); } byte[] counter = new byte[2]; byte[] cardChallenge = new byte[8]; byte[] cardCryptogram = new byte[8]; Array.Copy(response.ResponseData, 12, counter, 0, 2); Array.Copy(response.ResponseData, 12, cardChallenge, 0, 8); Array.Copy(response.ResponseData, 20, cardCryptogram, 0, 8); var tempSessionKeys = DaplugCrypto.ComputeSessionKeys(keyset, counter); var computedCardCryptogram = DaplugCrypto.CalculateCryptogram(tempSessionKeys, hostChallenge, cardChallenge); if (computedCardCryptogram.SequenceEqual(cardCryptogram) == false) { throw new DaplugAPIException("Invalid card cryptogram."); } var hostCryptogram = DaplugCrypto.CalculateCryptogram(tempSessionKeys, cardChallenge, hostChallenge); if (securityLevel.HasFlag(DaplugSecurityLevel.COMMAND_MAC) == false) { securityLevel |= DaplugSecurityLevel.COMMAND_MAC; } tempSessionKeys.SecurityLevel = securityLevel; SessionKeys = tempSessionKeys; var extAuthCommandHeader = new byte[] { 0x80, 0x82, (byte)SessionKeys.SecurityLevel, 0x00, 0x00 }; var extAuthCommand = new APDUCommand(extAuthCommandHeader, hostCryptogram); var extAuthResponse = await ExchangeAPDUAsync(extAuthCommand); if (extAuthResponse.IsSuccessfulResponse == false) { SessionKeys = null; throw new DaplugAPIException("EXTERNAL AUTHENTICATE failed.", response.SW1, response.SW2); } Array.Copy(SessionKeys.CMac, SessionKeys.RMac, 8); }