示例#1
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);
            }
        }
示例#2
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);
            }
        }
示例#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);
        }