예제 #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="data"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static byte[] ComputeMacForIntegrity(this byte[] data, KeyParameter key)
        {
            /*
             *  The computation of an s-byte MAC (4 ≤ s ≤ 8; see MAC algorithms) is according to ISO/IEC 9797-1 [2] using a 64-bit block cipher ALG in CBC mode as specified in ISO/IEC 10116. More precisely, the computation of a MAC S over a message MSG consisting of an arbitrary number of bytes with a MAC Session Key K$$_{{\rm S}}$$ takes place in the following steps:
             *  1.  Padding and Blocking
             *      Pad the message M according to ISO/IEC 7816-4 (which is equivalent to method 2 of ISO/IEC 9797-1), hence add a mandatory ‘80’ byte to the right of MSG, and then add the smallest number of ‘00’ bytes to the right such that the length of resulting message MSG := (MSG ‖ ‖ ‘80’ ‖ ‖ ‘00’ ‖ ‖ ‘00’ ‖ ‖ … ‖ ‖ ‘00’) is a multiple of 8 bytes.
             *      MSG is then divided into 8-byte blocks $$X_{1}$$, $$X_{2}$$, $$\ldots$$, $$X_{{\rm k}}$$.
             *  2.  MAC Session Key
             *      The MAC Session Key $$K_{{\rm S}}$$ either consists of only a leftmost key block $$K_{{\rm S}} = K_{{\rm SL}}$$ or the concatenation of a leftmost and a rightmost key block $$K_{{\rm S}} = (K_{{\rm SL} }\vert \vert K_{\rm SR})$$.
             *  3.  Cryptogram Computation
             *      Process the 8-byte blocks $$X_{1}$$, $$X_{2}$$, …, $$X_{{k}}$$ with the block cipher in CBC mode (see modes ofoperation) using the leftmost MAC Session Key block $$K_{{\rm SL}}$$:
             *      $${H}_{{i}} := {\rm ALG}({K}_{{\rm SL}})[{X}_{{i}} \oplus {H}_{{i} - 1}], {\rm for } i = 1, 2, \ldots, {k}$$
             *      with initial value $$H_{0}$$ := (‘00’ ‖ ‖ ‘00’ ‖ ‖ ‘00’ ‖ ‖ ‘00’ ‖ ‖ ‘00’ ‖ ‖ ‘00’ ‖ ‖ ‘00’ ‖ ‖ ‘00’).
             *      Compute the 8-byte block $$H_{{k} + 1}$$ in one of the following two ways:
             *      •   According to ISO/IEC 9797-1 Algorithm 1:
             *          $${H}_{{k}+1} := {H}_{{k}}.$$
             *      •   According to Optional Process 1 of ISO/IEC 9797-1 Algorithm 3:
             *          $${H}_{{k}+1} := {\rm    ALG}({K}_{{\rm SL}})[{\rm ALG}^{-1}({K}_{{\rm SR}})[{H}_{{k}}]].$$
             *  The MAC S is then equal to the s most significant bytes of $$H_{{k} + 1}$$.
             */
            IBlockCipher cipher = new DesEngine();
            IMac         mac    = new ISO9797Alg3Mac(cipher, 64, new ISO7816d4Padding());

            mac.Init(key);
            mac.BlockUpdate(data, 0, data.Length);

            var m = new byte[mac.GetMacSize()];

            mac.DoFinal(m, 0);

            return(m);
        }
예제 #2
0
        public override void PerformTest()
        {
            KeyParameter key    = new KeyParameter(keyBytes);
            IBlockCipher cipher = new DesEngine();
            IMac         mac    = new ISO9797Alg3Mac(cipher);

            //
            // standard DAC - zero IV
            //
            mac.Init(key);

            mac.BlockUpdate(input1, 0, input1.Length);

            byte[] outBytes = new byte[8];

            mac.DoFinal(outBytes, 0);

            if (!AreEqual(outBytes, output1))
            {
                Fail("Failed - expected " + Hex.ToHexString(output1) + " got " + Hex.ToHexString(outBytes));
            }

            //
            //  reset
            //
            mac.Reset();

            mac.Init(key);

            for (int i = 0; i != input1.Length / 2; i++)
            {
                mac.Update(input1[i]);
            }

            mac.BlockUpdate(input1, input1.Length / 2, input1.Length - (input1.Length / 2));

            mac.DoFinal(outBytes, 0);

            if (!AreEqual(outBytes, output1))
            {
                Fail("Reset failed - expected " + Hex.ToHexString(output1) + " got " + Hex.ToHexString(outBytes));
            }
        }
예제 #3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="data"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static byte[] ComputeMacForPersoCryptogram(this byte[] data, KeyParameter key)
        {
            IBlockCipher cipher = new DesEdeEngine();
            IMac         mac    = new ISO9797Alg3Mac(cipher, 64, new ISO7816d4Padding());

            mac.Init(key);
            mac.BlockUpdate(data, 0, data.Length);

            var m = new byte[mac.GetMacSize()];

            mac.DoFinal(m, 0);

            return(m);
        }
예제 #4
0
        //public byte[] Bytes()
        //{
        //    MACTripleDES mac = new MACTripleDES();
        //    mac.Initialize();
        //    mac.Padding = PaddingMode.Zeros;
        //    mac.Key = _kMac.Bytes();

        //    var eIfd = _eIfd.Bytes();
        //    var mIfd = mac.TransformFinalBlock(eIfd, 0, eIfd.Length);
        //    return mIfd;
        //}

        /// <summary>
        /// C# Implementation of Retail MAC Calculation (ISOIEC 9797-1 MAC algorithm 3)
        /// http://stackoverflow.com/questions/20312646/c-sharp-implementation-of-retail-mac-calculation-isoiec-9797-1-mac-algorithm-3
        /// </summary>
        /// <returns></returns>
        //public byte[] Bytes()
        //{
        //    var kMAC = _kMac.Bytes();
        //    var eIfd = _eIfd.Bytes();

        //    // Split the 16 byte MAC key into two keys
        //    byte[] key1 = new byte[8];
        //    Array.Copy(kMAC, 0, key1, 0, 8);
        //    byte[] key2 = new byte[8];
        //    Array.Copy(kMAC, 8, key2, 0, 8);


        //    // Padd the data with Padding Method 2 (Bit Padding)
        //    System.IO.MemoryStream out_Renamed = new System.IO.MemoryStream();
        //    out_Renamed.Write(eIfd, 0, eIfd.Length);
        //    out_Renamed.WriteByte((byte)(0x80));
        //    while (out_Renamed.Length % 8 != 0)
        //    {
        //        out_Renamed.WriteByte((byte)0x00);
        //    }
        //    byte[] eIfd_padded = out_Renamed.ToArray();


        //    // Split the blocks
        //    byte[] d1 = new byte[8];
        //    byte[] d2 = new byte[8];
        //    byte[] d3 = new byte[8];
        //    byte[] d4 = new byte[8];
        //    byte[] d5 = new byte[8];
        //    Array.Copy(eIfd_padded, 0, d1, 0, 8);
        //    Array.Copy(eIfd_padded, 8, d2, 0, 8);
        //    Array.Copy(eIfd_padded, 16, d3, 0, 8);
        //    Array.Copy(eIfd_padded, 24, d4, 0, 8);
        //    Array.Copy(eIfd_padded, 32, d5, 0, 8);

        //    DES des1 = DES.Create();
        //    des1.BlockSize = 64;
        //    des1.Key = key1;
        //    des1.Mode = CipherMode.CBC;
        //    des1.Padding = PaddingMode.None;
        //    des1.IV = new byte[8];

        //    DES des2 = DES.Create();
        //    des2.BlockSize = 64;
        //    des2.Key = key2;
        //    des2.Mode = CipherMode.CBC;
        //    des2.Padding = PaddingMode.None;
        //    des2.IV = new byte[8];

        //    // MAC Algorithm 3
        //    // Initial Transformation 1
        //    byte[] h1 = des1.CreateEncryptor().TransformFinalBlock(d1, 0, 8);
        //    // Iteration on the rest of blocks
        //    // XOR
        //    byte[] int2 = new byte[8];
        //    for (int i = 0; i < 8; i++)
        //        int2[i] = (byte)(h1[i] ^ d2[i]);
        //    // Encrypt
        //    byte[] h2 = des1.CreateEncryptor().TransformFinalBlock(int2, 0, 8);
        //    // XOR
        //    byte[] int3 = new byte[8];
        //    for (int i = 0; i < 8; i++)
        //        int3[i] = (byte)(h2[i] ^ d3[i]);
        //    // Encrypt
        //    byte[] h3 = des1.CreateEncryptor().TransformFinalBlock(int3, 0, 8);
        //    // XOR
        //    byte[] int4 = new byte[8];
        //    for (int i = 0; i < 8; i++)
        //        int4[i] = (byte)(h3[i] ^ d4[i]);
        //    // Encrypt
        //    byte[] h4 = des1.CreateEncryptor().TransformFinalBlock(int4, 0, 8);
        //    // XOR
        //    byte[] int5 = new byte[8];
        //    for (int i = 0; i < 8; i++)
        //        int5[i] = (byte)(h4[i] ^ d5[i]);
        //    // Encrypt
        //    byte[] h5 = des1.CreateEncryptor().TransformFinalBlock(int5, 0, 8);

        //    // Output Transformation 3
        //    byte[] h5decrypt = des2.CreateDecryptor().TransformFinalBlock(h5, 0, 8);
        //    byte[] mIfd = des1.CreateEncryptor().TransformFinalBlock(h5decrypt, 0, 8);

        //    return mIfd;
        //}

        // http://www.programcreek.com/java-api-examples/index.php?api=org.spongycastle.crypto.macs.ISO9797Alg3Mac
        public byte[] Bytes()
        {
            var cipher = new DesEngine();

            var macSizeInBits = 64; // 8 in bytes

            var          mac  = new ISO9797Alg3Mac(cipher, 64, new ISO7816d4Padding());
            KeyParameter keyP = new KeyParameter(_key.Bytes());

            mac.Init(keyP);
            mac.BlockUpdate(_data.Bytes(), 0, _data.Bytes().Length);
            byte[] _out = new byte[8];
            mac.DoFinal(_out, 0);
            return(_out);
        }