Example #1
0
        public static ByteArray GenerateRandom(int length, ByteArray sourceBytes)
        {
            ByteArray result = new ByteArray(length);

            result.Randomize(_random, sourceBytes);
            return(result);
        }
Example #2
0
        /// <summary>
        /// Uwierzytelnia do CM podanym kluczem
        /// </summary>
        public JavaCardKeys StartSecuredChannel(ByteArray motherKey, KeyDiversificationMethod diversification = KeyDiversificationMethod.None, SecurityControlMode securityMode = SecurityControlMode.NoSecurity, byte keyVersion = 0x00, byte referenceControlParameter2 = 0x00)
        {
            try
            {
                //losowanie danych terminala
                ByteArray terminalRandom = new ByteArray(8);
                terminalRandom.Randomize(random);

                //Initialize Update
                ByteArray response = InitializeUpdate(keyVersion, 00, terminalRandom);

                //z odpowiedzi wyciągamy dane
                byte scpId = response[11];
                if (scpId == 0x01)
                {
                    scp = SecureChannelProtocol.SCP01;
                }
                else if (scpId == 0x02)
                {
                    scp = SecureChannelProtocol.SCP02;
                }
                ByteArray sn             = response.Extract(4, 4);
                ByteArray aid            = response.Extract(0, 2);
                ByteArray cardRandom     = response.Extract(12, 8);
                ByteArray cardCryptogram = response.Extract(20, 8);

                Logger.Log("[JavaCard] \n{0}:\t{1}\n{2}:\t{3}\n{4}:\t{5}\n{6}:\t{7}\n{8}:\t{9}", "TerminalRandom", terminalRandom, "SN", sn, "AID", aid, "CardRandom", cardRandom, "CardCryptogram", cardCryptogram);

                //wyliczanie kluczy z matki
                switch (diversification)
                {
                case KeyDiversificationMethod.None:
                    Keys = new JavaCardKeys(motherKey);
                    break;

                case KeyDiversificationMethod.GPICSN:
                    Keys = GPICSerialDiversificate(motherKey, response);
                    break;

                case KeyDiversificationMethod.MPCOS3DES:
                    throw new Exception("Wybrany algorytm dywersyfikacji nie jest na razie wspierany");
                    break;

                case KeyDiversificationMethod.TagCF:
                    Keys = TagCFDiversificate(motherKey, response);
                    break;
                }

                //wyliczamy klucze sesyjne AUTH/ENC i MAC
                if (scp == SecureChannelProtocol.SCP01)
                {
                    ComputeSessionKeys(Keys, terminalRandom, cardRandom);
                }
                else if (scp == SecureChannelProtocol.SCP02)
                {
                    ComputeSessionKeys2(Keys, terminalRandom, cardRandom);
                }
                else
                {
                    throw new Exception("Nieobsługiwany protokół bezpiecznego kanału");
                }

                //weryfikujemy kryptogram zwrócony przez InitializeUpdate
                if (!CheckCardCryptogram(cardCryptogram, terminalRandom, cardRandom))
                {
                    throw new JavaCardAuthenticationException("Kryptogram zwrócony przez komendę InitializeUpdate nie zgadza się.");
                }

                //ExternalAuthenticate
                ByteArray externalAuthenticateCommand = new ByteArray("84 82") + (byte)securityMode + new ByteArray("00 10");
                ByteArray terminalCryptogram          = GenerateTerminalCryptogram(terminalRandom, cardRandom);
                ByteArray MAC = new ByteArray();
                if (scp == SecureChannelProtocol.SCP01)
                {
                    MAC = GenerateExAuthMAC(externalAuthenticateCommand, terminalCryptogram);
                }
                else if (scp == SecureChannelProtocol.SCP02)
                {
                    MAC = GenerateExAuthMAC2(externalAuthenticateCommand, terminalCryptogram);
                }
                ByteArray fullExternalAuthenticateCommand = externalAuthenticateCommand + terminalCryptogram + MAC;
                Encoder.SendCommand(fullExternalAuthenticateCommand);

                _securityMode = securityMode;
                _lastMAC      = MAC;
                _authenticatedKeySetVersion = response[10];
            }
            catch (APDUException exception)
            {
                _sessionKeys  = null;
                _securityMode = SecurityControlMode.NoSecurity;
                throw new JavaCardAuthenticationException("Błąd ustanowienia bezpiecznego kanału.", exception);
            }
            catch (Exception exception)
            {
                _sessionKeys  = null;
                _securityMode = SecurityControlMode.NoSecurity;
                throw new JavaCardAuthenticationException("Błąd ustanowienia bezpiecznego kanału.", exception);
            }

            return(_sessionKeys);
        }
Example #3
0
        /// <summary>
        /// Uwierzytelnia do CM podanymi kluczami
        /// </summary>
        /// <param name="keys">Klucze</param>
        /// <param name="keySet"></param>
        /// <param name="keyIndex"></param>
        /// <param name="securityMode"></param>
        public JavaCardKeys StartSecuredChannel(JavaCardKeys keys, SecurityControlMode securityMode, Byte keySet = 0, Byte keyIndex = 0)
        {
            try
            {
                //losowanie danych terminala
                ByteArray terminalRandom = new ByteArray(8);
                terminalRandom.Randomize(random);
                //terminalRandom = new ByteArray("00 00 00 00 00 00 00 00");

                //Initialize Update
                ByteArray initializeUpdateCommand = new ByteArray("80 50 00 00 08") + terminalRandom + new ByteArray("00");
                initializeUpdateCommand[2] = keySet;
                initializeUpdateCommand[3] = keyIndex;

                ByteArray response = Encoder.SendCommand(initializeUpdateCommand);

                //z odpowiedzi wyciągamy losowe dane karty i kryptogram
                ByteArray cardRandom     = response.Extract(12, 8);
                ByteArray cardCryptogram = response.Extract(20, 8);

                byte scpId = response[11];
                if (scpId == 0x01)
                {
                    scp = SecureChannelProtocol.SCP01;
                }
                else if (scpId == 0x02)
                {
                    scp = SecureChannelProtocol.SCP02;
                }

                //wyliczamy klucze sesyjne AUTH/ENC i MAC
                if (scp == SecureChannelProtocol.SCP01)
                {
                    ComputeSessionKeys(Keys, terminalRandom, cardRandom);
                }
                else if (scp == SecureChannelProtocol.SCP02)
                {
                    ComputeSessionKeys2(Keys, terminalRandom, cardRandom);
                }
                else
                {
                    throw new Exception("Nieobsługiwany protokół bezpiecznego kanału");
                }

                //weryfikujemy kryptogram zwrócony przez InitializeUpdate
                if (!CheckCardCryptogram(cardCryptogram, terminalRandom, cardRandom))
                {
                    throw new JavaCardAuthenticationException("Kryptogram zwrócony przez komendę InitializeUpdate nie zgadza się.");
                }

                //ExternalAuthenticate
                ByteArray externalAuthenticateCommand = new ByteArray("84 82") + (byte)securityMode + new ByteArray("00 10");
                ByteArray terminalCryptogram          = GenerateTerminalCryptogram(terminalRandom, cardRandom);
                ByteArray MAC = GenerateExAuthMAC(externalAuthenticateCommand, terminalCryptogram);

                ByteArray fullExternalAuthenticateCommand = externalAuthenticateCommand + terminalCryptogram + MAC;
                Encoder.SendCommand(fullExternalAuthenticateCommand);
                _securityMode = securityMode;
                _lastMAC      = MAC;
                _authenticatedKeySetVersion = response[10];
            }
            catch (APDUException exception)
            {
                _sessionKeys  = null;
                _securityMode = SecurityControlMode.NoSecurity;
                throw new JavaCardAuthenticationException("Błąd ustanowienia bezpiecznego kanału.", exception);
            }
            catch (Exception exception)
            {
                _sessionKeys  = null;
                _securityMode = SecurityControlMode.NoSecurity;
                throw new JavaCardAuthenticationException("Błąd ustanowienia bezpiecznego kanału.", exception);
            }
            return(_sessionKeys);
        }