示例#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 static byte[] Mac_des_3des(GPKey key, byte[] text, int offset, int length, byte[] iv)
        {
            if (length == -1)
            {
                length = text.Length - offset;
            }

            try
            {
                //Cipher cipher1 = Cipher.getInstance(DES_CBC_CIPHER);
                //cipher1.init(Cipher.ENCRYPT_MODE, key.getKey(Type.DES), new IvParameterSpec(iv));
                //Cipher cipher2 = Cipher.getInstance(DES3_CBC_CIPHER);
                //cipher2.init(Cipher.ENCRYPT_MODE, key.getKey(Type.DES3), new IvParameterSpec(iv));

                byte[] result = Arrays.Clone(iv);
                byte[] temp;
                if (length > 8)
                {
                    temp = GPCrypto.DoEncrypt_DES_CBC(key.GetKey(KeyType.DES).GetEncoded(), text, offset, length - 8, iv);
                    Array.Copy(temp, temp.Length - 8, result, 0, 8);
                }
                temp = GPCrypto.DoEncrypt_DES3_CBC(key.GetKey(KeyType.DES3).GetEncoded(), text, (offset + length) - 8, 8, result);
                Array.Copy(temp, temp.Length - 8, result, 0, 8);
                return(result);
            }
            catch (Exception e)
            {
                //e.printStackTrace();
                throw new Exception("MAC computation failed.", e);
            }
        }
示例#3
0
        public static GPPlaintextKeys FromMasterKey(GPKey master, Diversification div)
        {
            GPKeySet        ks = new GPKeySet(master);
            GPPlaintextKeys p  = new GPPlaintextKeys(ks, div)
            {
                master = master
            };

            return(p);
        }
示例#4
0
        public void AuthWithCard(byte[] mk, byte[] hostChallenge = null)
        {
            GPKey           kmc   = new GPKey(mk, KeyType.DES3);
            GPPlaintextKeys gpptk = GPPlaintextKeys.FromMasterKey(kmc, Diversification.VISA2);

            gp.OpenSecureChannel(gpptk, new List <APDUMode>()
            {
                APDUMode.CLR
            }, hostChallenge);
        }
示例#5
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);
            }
        }
示例#6
0
 private static byte[] Scp03_key_check_value(GPKey key)
 {
     try
     {
         byte[] cv = GPCrypto.DoEncrypt_AES_CBC(key.GetKey().GetEncoded(), GPCrypto.one_bytes_16);
         //Cipher c = Cipher.getInstance(AES_CBC_CIPHER);
         //c.init(Cipher.ENCRYPT_MODE, key.getKey(), iv_null_aes);
         //byte[] cv = c.doFinal(one_bytes_16);
         return(Arrays.CopyOfRange(cv, 0, 3));
     }
     catch (Exception e)
     {
         throw new Exception("Could not calculate key check value: ", e);
     }
 }
示例#7
0
        //public static IvParameterSpec iv_null_des = new IvParameterSpec(null_bytes_8);
        //public static IvParameterSpec iv_null_aes = new IvParameterSpec(null_bytes_16);

        public static byte[] Kcv_3des(GPKey key)
        {
            try
            {
                byte[] check = DoEncrypt_DES3_ECB(key.GetKey().GetEncoded(), null_bytes_8);
                //Cipher cipher = Cipher.getInstance("DESede/ECB/NoPadding");
                //cipher.init(Cipher.ENCRYPT_MODE, key.getKey());
                //byte check[] = cipher.doFinal(GPCrypto.null_bytes_8);
                return(Arrays.CopyOf(check, 3));
            }
            catch (Exception e)
            {
                throw new Exception("Could not calculate KCV", e);
            }
        }
示例#8
0
 private static byte[] Scp03_encrypt_key(GPKey kek, GPKey key)
 {
     try
     {
         // Pad with random
         int          n         = key.GetLength() % 16 + 1;
         byte[]       plaintext = new byte[n * 16];
         SecureRandom sr        = new SecureRandom();
         sr.NextBytes(plaintext);
         Array.Copy(key.GetValue(), 0, plaintext, 0, key.GetValue().Length);
         // encrypt
         byte[] cgram = GPCrypto.DoEncrypt_AES_CBC(kek.GetValue(), plaintext);
         //Cipher c = Cipher.getInstance(AES_CBC_CIPHER);
         //c.init(Cipher.ENCRYPT_MODE, kek.GetEncoded(), null_bytes_16);
         //byte[] cgram = c.doFinal(plaintext);
         return(cgram);
     }
     catch (Exception e)
     {
         throw new Exception("Could not calculate key check value: ", e);
     }
 }
示例#9
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);
            }
        }
示例#10
0
 public static GPPlaintextKeys FromMasterKey(GPKey master)
 {
     return(FromMasterKey(master, Diversification.NONE));
 }
示例#11
0
 public void SetKey(KeySessionType type, GPKey k)
 {
     keys.Add(type, k);
 }
示例#12
0
 public GPKeySet(GPKey master)
 {
     keys.Add(KeySessionType.ENC, master);
     keys.Add(KeySessionType.MAC, master);
     keys.Add(KeySessionType.KEK, master);
 }
示例#13
0
 // SCP03 related
 private static byte[] Scp03_mac(GPKey key, byte[] msg, int lengthbits)
 {
     return(Scp03_mac(key.GetValue(), msg, lengthbits));
 }
示例#14
0
 // GP 2.2.1 Amendment D v 1.1.1
 public static byte[] Scp03_kdf(GPKey key, byte constant, byte[] context, int blocklen_bits)
 {
     return(Scp03_kdf(key.GetValue(), constant, context, blocklen_bits));
 }
示例#15
0
 private static byte[] Mac_des_3des(GPKey key, byte[] text, byte[] iv)
 {
     byte[] d = Pad80(text, 8);
     return(Mac_des_3des(key, d, 0, d.Length, iv));
 }
示例#16
0
 public static byte[] Mac_3des_nulliv(GPKey key, byte[] d)
 {
     return(Mac_3des(key, d, GPCrypto.null_bytes_8));
 }