예제 #1
0
        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);
            }
        }
예제 #2
0
        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);
        }
예제 #3
0
        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);
        }