示例#1
0
        private GPKeySet DeriveSessionKeysSCP01(GPKeySet staticKeys, byte[] host_challenge, byte[] card_challenge)
        {
            GPKeySet sessionKeys = new GPKeySet();

            byte[] derivationData = new byte[16];
            Array.Copy(card_challenge, 4, derivationData, 0, 4);
            Array.Copy(host_challenge, 0, derivationData, 4, 4);
            Array.Copy(card_challenge, 0, derivationData, 8, 4);
            Array.Copy(host_challenge, 4, derivationData, 12, 4);

            try
            {
                //Cipher cipher = Cipher.getInstance("DESede/ECB/NoPadding");
                foreach (KeySessionType v in KeyTypeList.Values)
                {
                    if (v == KeySessionType.RMAC) // skip RMAC key
                    {
                        continue;
                    }
                    //cipher.init(Cipher.ENCRYPT_MODE, staticKeys.getKeyFor(v));
                    //GPKey nk = new GPKey(cipher.doFinal(derivationData), Type.DES3);
                    byte[] result = GPCrypto.DoEncrypt_DES3_ECB(staticKeys.GetKeyFor(v).GetEncoded(), derivationData);
                    GPKey  nk     = new GPKey(result, KeyType.DES3);

                    sessionKeys.SetKey(v, nk);
                }
                // KEK is the same
                sessionKeys.SetKey(KeySessionType.KEK, staticKeys.GetKey(KeySessionType.KEK));
                return(sessionKeys);
            }
            //catch (NoSuchAlgorithmException e)
            //{
            //    throw new IllegalStateException("Session keys calculation failed.", e);
            //}
            //catch (NoSuchPaddingException e)
            //{
            //    throw new IllegalStateException("Session keys calculation failed.", e);
            //}
            //catch (InvalidKeyException e)
            //{
            //    throw new RuntimeException("Session keys calculation failed.", e);
            //}
            //catch (IllegalBlockSizeException e)
            //{
            //    throw new RuntimeException("Session keys calculation failed.", e);
            //}
            //catch (BadPaddingException e)
            //{
            //    throw new RuntimeException("Session keys calculation failed.", e);
            //}
            catch (Exception e)
            {
                throw new Exception("Session keys calculation failed.", e);
            }
        }
示例#2
0
        public static GPKeySet Diversify(GPKeySet keys, byte[] diversification_data, Diversification mode, int scp)
        {
            try
            {
                GPKeySet result = new GPKeySet();
                //Cipher cipher = Cipher.getInstance("DESede/ECB/NoPadding");
                foreach (KeySessionType v in KeyTypeList.Values)
                {
                    if (v == KeySessionType.RMAC)
                    {
                        continue;
                    }
                    byte[] kv = null;
                    // shift around and fill initialize update data as required.
                    if (mode == Diversification.VISA2)
                    {
                        kv = FillVisa(diversification_data, v);
                    }
                    else if (mode == Diversification.EMV)
                    {
                        kv = FillEmv(diversification_data, v);
                    }

                    // Encrypt with current master key
                    //cipher.init(Cipher.ENCRYPT_MODE, keys.getKey(v).getKey(Type.DES3));
                    //byte[] keybytes = cipher.doFinal(kv);
                    byte[] keybytes = GPCrypto.DoEncrypt_DES3_ECB(keys.GetKey(v).GetKey(KeyType.DES3).GetEncoded(), kv);

                    // Replace the key, possibly changing type. G&D SCE 6.0 uses EMV 3DES and resulting keys
                    // must be interpreted as AES-128
                    GPKey nk = new GPKey(keybytes, scp == 3 ? KeyType.AES : KeyType.DES3);
                    result.SetKey(v, nk);
                }
                return(result);
            }
            //catch (BadPaddingException e)
            //{
            //    throw new Exception("Diversification failed.", e);
            //}
            //catch (InvalidKeyException e)
            //{
            //    throw new Exception("Diversification failed.", e);
            //}
            //catch (IllegalBlockSizeException e)
            //{
            //    throw new Exception("Diversification failed.", e);
            //}
            //catch (NoSuchAlgorithmException e)
            //{
            //    throw new Exception("Diversification failed.", e);
            //}
            //catch (NoSuchPaddingException e)
            //{
            //    throw new Exception("Diversification failed.", e);
            //}
            catch (Exception e)
            {
                throw new Exception("Diversification failed.", e);
            }
        }
示例#3
0
        private GPKeySet DeriveSessionKeysSCP03(GPKeySet staticKeys, byte[] host_challenge, byte[] card_challenge)
        {
            GPKeySet sessionKeys   = new GPKeySet();
            byte     mac_constant  = 0x06;
            byte     enc_constant  = 0x04;
            byte     rmac_constant = 0x07;

            byte[] context = Arrays.Concatenate(host_challenge, card_challenge);

            // MAC
            byte[] kdf = SCP03Wrapper.Scp03_kdf(staticKeys.GetKey(KeySessionType.MAC), mac_constant, context, 128);
            sessionKeys.SetKey(KeySessionType.MAC, new GPKey(kdf, KeyType.AES));
            // ENC
            kdf = SCP03Wrapper.Scp03_kdf(staticKeys.GetKey(KeySessionType.ENC), enc_constant, context, 128);
            sessionKeys.SetKey(KeySessionType.ENC, new GPKey(kdf, KeyType.AES));
            // RMAC
            kdf = SCP03Wrapper.Scp03_kdf(staticKeys.GetKey(KeySessionType.MAC), rmac_constant, context, 128);
            sessionKeys.SetKey(KeySessionType.RMAC, new GPKey(kdf, KeyType.AES));

            // KEK remains the same
            sessionKeys.SetKey(KeySessionType.KEK, staticKeys.GetKey(KeySessionType.KEK));
            return(sessionKeys);
        }
示例#4
0
        private GPKeySet DeriveSessionKeysSCP02(GPKeySet staticKeys, byte[] sequence, bool implicitChannel)
        {
            GPKeySet sessionKeys = new GPKeySet();

            try
            {
                //Cipher cipher = Cipher.getInstance("DESede/CBC/NoPadding");

                byte[] derivationData = new byte[16];
                Array.Copy(sequence, 0, derivationData, 2, 2);

                byte[] constantMAC = new byte[] { (byte)0x01, (byte)0x01 };
                Array.Copy(constantMAC, 0, derivationData, 0, 2);
                //cipher.init(Cipher.ENCRYPT_MODE, staticKeys.getKeyFor(KeySessionType.MAC), GPCrypto.iv_null_des);
                //GPKey nk = new GPKey(cipher.doFinal(derivationData), Type.DES3);
                byte[] result = GPCrypto.DoEncrypt_DES3_CBC(staticKeys.GetKeyFor(KeySessionType.MAC).GetEncoded(), derivationData);
                GPKey  nk     = new GPKey(result, KeyType.DES3);

                sessionKeys.SetKey(KeySessionType.MAC, nk);

                // TODO: is this correct? - increment by one for all other than C-MAC
                if (implicitChannel)
                {
                    Buffer_increment(derivationData, 2, 2);
                }

                byte[] constantRMAC = new byte[] { (byte)0x01, (byte)0x02 };
                Array.Copy(constantRMAC, 0, derivationData, 0, 2);
                //cipher.init(Cipher.ENCRYPT_MODE, staticKeys.getKeyFor(KeySessionType.MAC), GPCrypto.iv_null_des);
                //nk = new GPKey(cipher.doFinal(derivationData), Type.DES3);
                byte[] result2 = GPCrypto.DoEncrypt_DES3_CBC(staticKeys.GetKeyFor(KeySessionType.MAC).GetEncoded(), derivationData);
                nk = new GPKey(result2, KeyType.DES3);

                sessionKeys.SetKey(KeySessionType.RMAC, nk);

                byte[] constantENC = new byte[] { (byte)0x01, (byte)0x82 };
                Array.Copy(constantENC, 0, derivationData, 0, 2);
                //cipher.init(Cipher.ENCRYPT_MODE, staticKeys.getKeyFor(KeySessionType.ENC), GPCrypto.iv_null_des);
                //nk = new GPKey(cipher.doFinal(derivationData), Type.DES3);
                byte[] result3 = GPCrypto.DoEncrypt_DES3_CBC(staticKeys.GetKeyFor(KeySessionType.ENC).GetEncoded(), derivationData);
                nk = new GPKey(result3, KeyType.DES3);

                sessionKeys.SetKey(KeySessionType.ENC, nk);

                byte[] constantDEK = new byte[] { (byte)0x01, (byte)0x81 };
                Array.Copy(constantDEK, 0, derivationData, 0, 2);
                //cipher.init(Cipher.ENCRYPT_MODE, staticKeys.getKeyFor(KeySessionType.KEK), GPCrypto.iv_null_des);
                //nk = new GPKey(cipher.doFinal(derivationData), Type.DES3);
                byte[] result4 = GPCrypto.DoEncrypt_DES3_CBC(staticKeys.GetKeyFor(KeySessionType.KEK).GetEncoded(), derivationData);
                nk = new GPKey(result4, KeyType.DES3);

                sessionKeys.SetKey(KeySessionType.KEK, nk);
                return(sessionKeys);
            }
            //catch (NoSuchAlgorithmException e)
            //{
            //    throw new IllegalStateException("Session keys calculation failed.", e);
            //}
            //catch (NoSuchPaddingException e)
            //{
            //    throw new IllegalStateException("Session keys calculation failed.", e);
            //}
            //catch (InvalidKeyException e)
            //{
            //    throw new RuntimeException("Session keys calculation failed.", e);
            //}
            //catch (IllegalBlockSizeException e)
            //{
            //    throw new RuntimeException("Session keys calculation failed.", e);
            //}
            //catch (BadPaddingException e)
            //{
            //    throw new RuntimeException("Session keys calculation failed.", e);
            //}
            //catch (InvalidAlgorithmParameterException e)
            //{
            //    throw new RuntimeException("Session keys calculation failed.", e);
            //}
            catch (Exception e)
            {
                throw new Exception("Session keys calculation failed.", e);
            }
        }