예제 #1
0
 /// <summary>
 /// Applies full triple DES MAC as defined in [ISO 9797-1] as MAC Algorithm 1 with output transformation 1, 
 /// without truncation, and withtriple DES taking the place of the block cipher. 
 /// See Global Platform 2.1.1 Card Spec Section B.1.2.1
 /// </summary>
 /// <param name="key">3DES key</param>
 /// <param name="iv">Initial Vector</param>
 /// <param name="data">Data to MAC</param>
 /// <returns>Full triple DES MAC</returns>
 public static byte[] FullTripleDESMAC(Key key, byte[] iv, byte[] data)
 {
     byte[] enc = TripleDESCBC(new Key(key.BuildTripleDesKey()), iv, data, MODE_ENCRYPT);
     byte[] result = new byte[8];
     Array.Copy(enc, enc.Length - 8, result, 0, 8);
     return result;
 }
예제 #2
0
        /// <summary>
        /// Applies Retail MAC as defined in [ISO 9797-1] as MAC Algorithm 1 with output 
        /// transformation 3, without truncation, and withDES taking the place of the block cipher. 
        /// </summary>
        /// <param name="key">Key</param>
        /// <param name="iv">Initial Vector</param>
        /// <param name="data">Data to MAC</param>
        /// <returns>Retial MAC</returns>

        public static byte[] SingleDESFullTripleDESMAC(Key key, byte[] iv, byte[] data)
        {
            byte[] intermeidateResult;
            byte[] result = new byte[8];
            if (data.Length > 8)
            {
                intermeidateResult = DESCBC(new Key(key.BuildDesKey()), iv, SubArray(data, 0, data.Length - 8), MODE_ENCRYPT);
                Array.Copy(intermeidateResult, intermeidateResult.Length - 8, result, 0, 8);
                intermeidateResult = TripleDESCBC(new Key(key.BuildTripleDesKey()), result, SubArray(data, data.Length - 8, 8), MODE_ENCRYPT);
            }
            else
            {
                intermeidateResult = TripleDESCBC(new Key(key.BuildTripleDesKey()), iv, SubArray(data, data.Length - 8, 8), MODE_ENCRYPT);
            }
            Array.Copy(intermeidateResult, intermeidateResult.Length - 8, result, 0, 8);
            return result;
        }
예제 #3
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="keys"></param>
        /// <param name="replaceExisting"></param>
        /// <param name="keyFormat"></param>
        /// <returns></returns>
        public CommandAPDU CreatePutKeyCommand(List<Key> keys, bool replaceExisting, bool addKCV, int keyFormat)
        {
            int p1;
            int p2;
            if (keyFormat == KEY_FORMAT_2)
                throw new Exception("Format 2 is reserved for futrue use.");
            if (keyFormat != KEY_FORMAT_1)
                throw new Exception("Unknown format");

            int prevId = -1;
            for (int i = 0; i < keys.Count; i++)
            {
                Key key = keys[i];
                if (i > 1)
                    if (key.KeyId != prevId + 1)
                        throw new Exception("Key Identifiers must sequentially increment. See See Global Platform 2.1.1 Card Spec section 9.8.2.3.1");
                prevId = key.KeyId;
            }

            if (replaceExisting)
                p1 = keys[0].KeyVersion;
            else
            {
                p1 = 0;
            }

            p2 = keys[0].KeyId;

            // Multiple keys
            if (keys.Count > 1)
                p2 |= 0x80;

            Key kek = null;
            if (mSCPIdentifier == SCP_01)
                kek = new Key(mStaticKeys.KekKey.BuildTripleDesKey());
            else if(mSCPIdentifier == SCP_02)
            {
                kek = new Key(mSessionKeys.KekKey.BuildTripleDesKey());
            }

            MemoryStream allKeyData = new MemoryStream();
            allKeyData.WriteByte((byte)keys[0].KeyVersion);
            for (int i = 0; i < keys.Count; i++)
            {
                Key key = keys[i];
                byte[] keyDataBytes = EncodeKeyData(key, kek, addKCV, keyFormat);
                allKeyData.Write(keyDataBytes, 0, keyDataBytes.Length);
                
            }
            CommandAPDU putKeyCommand = new CommandAPDU(CLA_GP, INS_PUT_KEY, p1, p2, allKeyData.ToArray(), 0x00);
            putKeyCommand = mSecureChannel.wrap(putKeyCommand);
            return putKeyCommand;
        }
예제 #4
0
 /// <summary>
 /// Encrypts or decrypts <see cref="data"/> with DES/CBC/NoPadding
 /// </summary>
 /// <param name="key">Key</param>
 /// <param name="iv">Initial Vector</param>
 /// <param name="data">Data to encrypt or decrypt</param>
 /// <param name="mode">Operation mode: either <see cref="MODE_ENCRYPT"/> or <see cref="MODE_DECRYPT"/> </param>
 /// <returns></returns>
 public static byte[] DESCBC(Key key, byte[] iv, byte[] data, int operationMode)
 {
     byte[] result = null;
     DESCryptoServiceProvider tdes = new DESCryptoServiceProvider();
     if (operationMode == MODE_DECRYPT)
     {
         tdes.Mode = CipherMode.CBC;
         tdes.Padding = PaddingMode.None;
         ICryptoTransform decryptor = tdes.CreateDecryptor(key.Value, iv);
         result = decryptor.TransformFinalBlock(data, 0, data.Length);
     }
     else if (operationMode == MODE_ENCRYPT)
     {
         tdes.Mode = CipherMode.CBC;
         tdes.Padding = PaddingMode.None;
         ICryptoTransform encryptor = tdes.CreateEncryptor(key.Value, iv);
         result = encryptor.TransformFinalBlock(data, 0, data.Length);
     }
     return result;
 }
예제 #5
0
        private byte[] EncodeKeyData(Key key, Key kek, bool addKCV, int keyFormat)
        {
            MemoryStream keyData = new MemoryStream();
            if (keyFormat == KEY_FORMAT_1)
            {
                // Key encryption algorithm
                keyData.WriteByte(CryptoUtil.ALG_DES);

                // Encrypted key data length
                keyData.WriteByte(0x10);

                byte[] encryptedKey = CryptoUtil.TripleDESECB(kek, key.Value, CryptoUtil.MODE_ENCRYPT);
                keyData.Write(encryptedKey, 0, encryptedKey.Length);

                if (addKCV)
                {

                    // KCV length
                    keyData.WriteByte(0x03);

                    // Calculate KCV
                    byte[] kcv = CryptoUtil.TripleDESECB(new Key(key.BuildTripleDesKey()),
                        CryptoUtil.BINARY_ZEROS_8_BYTE_BLOCK,
                        CryptoUtil.MODE_ENCRYPT);
                    keyData.Write(kcv, 0, 3);
                }
                else
                {
                    keyData.WriteByte(0x00);
                }
            }

            return keyData.ToArray();
        }