Ejemplo n.º 1
0
        public byte[] ReadData(byte[] sessionKey, byte[] updatedIV, byte fileNo)
        {
            byte[] offset = new byte[] { 0x00, 0x00, 0x00 }; //offset of 0
            byte[] length = new byte[] { 0x00, 0x00, 0x01 }; //length of 1

            byte[] dataForCMAC = new byte[] { (byte)DesfireCommand.CommandType.ReadData, fileNo, offset[2], offset[1], offset[0], length[2], length[1], length[0] };
            byte[] cmac        = AESCMAC.CMAC(
                sessionKey,
                updatedIV,
                dataForCMAC);

            updatedIV = cmac;

            byte[]         cmdToSend      = new byte[] { fileNo, offset[2], offset[1], offset[0], length[2], length[1], length[0] };
            DesfireCommand desfireCommand = new DesfireCommand()
            {
                Command = (byte)DesfireCommand.CommandType.ReadData,
                Data    = cmdToSend
            };
            DesfireResponse desfireRes = SendCommand(desfireCommand) as DesfireResponse;

            if (!desfireRes.Succeeded)
            {
                throw new DesFireException("Error:" + desfireRes.SW);
            }

            byte[] dataBytes = AESCrypto.AESDecrypt(
                sessionKey,
                updatedIV,
                desfireRes.ResponseData);

            byte[] extractIV = new byte[16];
            Array.Copy(desfireRes.ResponseData, desfireRes.ResponseData.Length - 16, extractIV, 0, 16);

            int lengthofData = 0x01;

            byte[] data = new byte[lengthofData];
            Array.Copy(dataBytes, data, data.Length);
            byte[] crc = new byte[4];
            Array.Copy(dataBytes, data.Length, crc, 0, crc.Length); //crc is 4 bytes long
            byte[] dataPlusStatus = new byte[data.Length + 1];
            Array.Copy(data, dataPlusStatus, data.Length);
            Array.Copy(new byte[] { 0x00 }, 0, dataPlusStatus, data.Length, 1);
            uint crc32 = Crc32.Compute(dataPlusStatus);

            //compare crc32 to crc
            if (BitConverter.ToUInt32(crc, 0) != crc32)
            {
                throw new DesFireException("CRC32 error");
            }
            return(data);
        }
Ejemplo n.º 2
0
        public byte[] AuthenticateAES()
        {
            string initialIV = "00000000000000000000000000000000";
            string key       = "00000000000000000000000000000000";

            DesfireCommand desfireCommand = new DesfireCommand()
            {
                Command = (byte)DesfireCommand.CommandType.AuthenticateAES,
                Data    = new byte[] { 0x00 } //1 byte key number
            };
            DesfireResponse desfireRes1 = SendCommand(desfireCommand) as DesfireResponse;

            if (!desfireRes1.SubsequentFrame) //additional frames expected
            {
                throw new DesFireException("Error:" + desfireRes1.SW);
            }

            byte[] rndBBytes = AESCrypto.AESDecrypt(
                Formatting.HexStringToByteArray(key),
                Formatting.HexStringToByteArray(initialIV),
                desfireRes1.ResponseData);

            byte[] rndBRotatedBytes    = Formatting.RotateRight(rndBBytes);
            string rndAGenerated       = "2347C1557F80707ABDFF86BF9D965CA7";
            string rndAPlusRndBRotated = rndAGenerated + Formatting.ByteArrayToHexString(rndBRotatedBytes);

            string ivNew = Formatting.ByteArrayToHexString(desfireRes1.ResponseData);

            byte[] rndAPlusRndBRotatedCipherBytes = AESCrypto.AESEncrypt(
                Formatting.HexStringToByteArray(key),
                Formatting.HexStringToByteArray(ivNew),
                Formatting.HexStringToByteArray(rndAPlusRndBRotated));

            desfireCommand = new DesfireCommand()
            {
                Command = (byte)DesfireCommand.CommandType.GetAdditionalFrame,
                Data    = rndAPlusRndBRotatedCipherBytes //32 byte enciphered RndA/RndB
            };
            byte[] extractIV = new byte[16];
            Array.Copy(rndAPlusRndBRotatedCipherBytes, rndAPlusRndBRotatedCipherBytes.Length - 16, extractIV, 0, 16);

            DesfireResponse desfireRes2 = SendCommand(desfireCommand) as DesfireResponse;

            if (!desfireRes2.Succeeded)
            {
                throw new DesFireException("Error:" + desfireRes2.SW);
            }

            byte[] rndARotatedBytes = AESCrypto.AESDecrypt(
                Formatting.HexStringToByteArray(key),
                extractIV,
                desfireRes2.ResponseData);

            byte[] rndABytes = Formatting.RotateLeft(rndARotatedBytes);
            if (rndAGenerated != Formatting.ByteArrayToHexString(rndABytes))
            {
                throw new DesFireException("rndA generated not same as rndA received");
            }

            string rndAString = Formatting.ByteArrayToHexString(rndABytes);
            string rndBString = Formatting.ByteArrayToHexString(rndBBytes);

            string sessionKey = rndAString.Substring(0, 8) + rndBString.Substring(0, 8) +
                                rndAString.Substring(24, 8) + rndBString.Substring(24, 8);

            return(Formatting.HexStringToByteArray(sessionKey));
        }