/// <summary> /// Wraps the PCSC function /// LONG SCardTransmit( /// SCARDHANDLE hCard, /// LPCSCARD_I0_REQUEST pioSendPci, /// LPCBYTE pbSendBuffer, /// DWORD cbSendLength, /// LPSCARD_IO_REQUEST pioRecvPci, /// LPBYTE pbRecvBuffer, /// LPDWORD pcbRecvLength /// ); /// </summary> /// <param name="ApduCmd">APDUCommand object with the APDU to send to the card</param> /// <returns>An APDUResponse object with the response from the card</returns> public override APDUResponse Transmit(APDUCommand ApduCmd) { CSCardCmd itfCmd = new CSCardCmdClass(); CByteBuffer itfData = new CByteBufferClass(); int nLe = ApduCmd.Le; if (ApduCmd.Data == null) { itfData.SetSize(0); } else { int nWrite = 0; itfData.SetSize(ApduCmd.Data.Length); itfData.Write(ref ApduCmd.Data[0], ApduCmd.Data.Length, ref nWrite); } // Build the APDU command itfCmd.BuildCmd(ApduCmd.Class, ApduCmd.Ins, ApduCmd.P1, ApduCmd.P2, itfData, ref nLe); // Send the command m_itfCard.Transaction(ref itfCmd); // Analyse the response int nRead = 0; byte[] pbResp = new byte[itfCmd.ApduReplyLength]; itfCmd.ApduReply.Read(ref pbResp[0], itfCmd.ApduReplyLength, ref nRead); return(new APDUResponse(pbResp)); }
public bool Check(out BigInteger CardNumber) { bool Result = false; byte[] UID, ADM1, ADM2; CardNumber = 0; const byte KEY_ADM1 = 0x0A, KEY_ADM2 = 0x0B; APDUCommand SelectFileCommand = new APDUCommand(0x00, 0xA4, 0x00, 0x00, null, 0x00), ReadCommand = new APDUCommand(0x00, 0xB0, 0x00, 0x00, null, 0x00), VerifyCommand = new APDUCommand(0x00, 0x20, 0x00, 0x00, null, 0x00); if (Execute("Select application", SelectApplicationCommand)) { SelectFileCommand.Data = new byte[] { 0x2F, 0x00 }; if (Execute("Select 2F00 (UID)", SelectFileCommand)) { ReadCommand.Le = 16; // читаем 16 байт UID if (Execute("Read UID from 2F00", ReadCommand)) { UID = new byte[Response.Data.Length]; Response.Data.CopyTo(UID, 0); Log.Log(2, "UID: " + Functions.ByteArrayToString(UID)); // генерируем ADM1 и ADM2 Crypto.GetADMForUID(UID, out ADM1, out ADM2); VerifyCommand.P2 = KEY_ADM1; VerifyCommand.Data = ADM1; if (Execute("Verify ADM1", VerifyCommand)) { VerifyCommand.P2 = KEY_ADM2; VerifyCommand.Data = ADM2; if (Execute("Verify ADM2", VerifyCommand)) { SelectFileCommand.Data = new byte[] { 0x2F, 0x01 }; if (Execute("Select 2F01 (CardNumber)", SelectFileCommand)) { ReadCommand.Le = 12; // читаем 12 байт номера карты if (Execute("Read CardNumber from 2F01", ReadCommand)) { Log.Log(2, "CardNumber bytes: " + Functions.ByteArrayToString(Response.Data)); // преобразование номера карты в число byte Length = Response.Data[0]; byte[] CardNumberBCD = new byte[Length]; Array.Copy(Response.Data, 1, CardNumberBCD, 0, Length); CardNumber = BigInteger.Parse(Functions.BCDToString(CardNumberBCD)); Result = true; } } } } } } } return Result; }
/// <summary> /// Wraps the PCSC function /// LONG SCardTransmit( /// SCARDHANDLE hCard, /// LPCSCARD_I0_REQUEST pioSendPci, /// LPCBYTE pbSendBuffer, /// DWORD cbSendLength, /// LPSCARD_IO_REQUEST pioRecvPci, /// LPBYTE pbRecvBuffer, /// LPDWORD pcbRecvLength /// ); /// </summary> /// <param name="ApduCmd">APDUCommand object with the APDU to send to the card</param> /// <returns>An APDUResponse object with the response from the card</returns> public override APDUResponse Transmit(APDUCommand ApduCmd) { uint RecvLength = (uint)(ApduCmd.Le + APDUResponse.SW_LENGTH); byte[] ApduBuffer = null; byte[] ApduResponse = new byte[ApduCmd.Le + APDUResponse.SW_LENGTH]; SCard_IO_Request ioRequest = new SCard_IO_Request(); ioRequest.m_dwProtocol = m_nProtocol; ioRequest.m_cbPciLength = 8; // Build the command APDU if (ApduCmd.Data == null) { ApduBuffer = new byte[APDUCommand.APDU_MIN_LENGTH + ((ApduCmd.Le != 0) ? 1 : 0)]; if (ApduCmd.Le != 0) { ApduBuffer[4] = (byte)ApduCmd.Le; } } else { ApduBuffer = new byte[APDUCommand.APDU_MIN_LENGTH + 1 + ApduCmd.Data.Length]; for (int nI = 0; nI < ApduCmd.Data.Length; nI++) { ApduBuffer[APDUCommand.APDU_MIN_LENGTH + 1 + nI] = ApduCmd.Data[nI]; } ApduBuffer[APDUCommand.APDU_MIN_LENGTH] = (byte)ApduCmd.Data.Length; } ApduBuffer[0] = ApduCmd.Class; ApduBuffer[1] = ApduCmd.Ins; ApduBuffer[2] = ApduCmd.P1; ApduBuffer[3] = ApduCmd.P2; m_nLastError = SCardTransmit(m_hCard, ref ioRequest, ApduBuffer, (uint)ApduBuffer.Length, IntPtr.Zero, ApduResponse, out RecvLength); if (m_nLastError != 0) { string msg = "SCardTransmit error: " + new Win32Exception(m_nLastError).Message; throw new Exception(msg); } byte[] ApduData = new byte[RecvLength]; for (int nI = 0; nI < RecvLength; nI++) { ApduData[nI] = ApduResponse[nI]; } return(new APDUResponse(ApduData)); }
public void BF() { Log.Log(0, "Brute started"); APDUCommand SelectCommand = new APDUCommand(0x00, 0xA4, 0x00, 0x00, null, 0x00); SelectCommand.Data = new byte[] { 0x52, 0x6f, 0x73, 0x54, 0x6f, 0x70, 0x53, 0x6f, 0x79, 0x75, 0x7a, 0x01 }; // 52 6F 73 54 6F 70 53 6F 79 75 7A 01 for (int P1 = 0; P1 <= 0xFF; P1++) for (int P2 = 0; P2 <= 0xFF; P2++) { SelectCommand.P1 = (byte)P1; SelectCommand.P2 = (byte)P2; if (Execute("", SelectCommand)) Log.Log(1, "P1 = {0}, P2 = {1}", P1, P2); if (Response.Status != 0x6A86) Log.Log(1, "Status: {0}", Response.Status.ToString("X")); Application.DoEvents(); } Log.Log(0, "Brute stopped"); }
/// <summary> /// Wraps the PCSC function /// LONG SCardTransmit( /// SCARDHANDLE hCard, /// LPCSCARD_I0_REQUEST pioSendPci, /// LPCBYTE pbSendBuffer, /// DWORD cbSendLength, /// LPSCARD_IO_REQUEST pioRecvPci, /// LPBYTE pbRecvBuffer, /// LPDWORD pcbRecvLength /// ); /// </summary> /// <param name="ApduCmd">APDUCommand object with the APDU to send to the card</param> /// <returns>An APDUResponse object with the response from the card</returns> public override APDUResponse Transmit(APDUCommand ApduCmd) { byte[] ApduBuffer = null; // Build the command APDU if (ApduCmd.Data == null) { ApduBuffer = new byte[APDUCommand.APDU_MIN_LENGTH + ((ApduCmd.Le != 0) ? 1 : 0)]; if (ApduCmd.Le != 0) { ApduBuffer[4] = (byte)ApduCmd.Le; } } else { ApduBuffer = new byte[APDUCommand.APDU_MIN_LENGTH + 1 + ApduCmd.Data.Length]; for (int nI = 0; nI < ApduCmd.Data.Length; nI++) { ApduBuffer[APDUCommand.APDU_MIN_LENGTH + 1 + nI] = ApduCmd.Data[nI]; } ApduBuffer[APDUCommand.APDU_MIN_LENGTH] = (byte)ApduCmd.Data.Length; } ApduBuffer[0] = ApduCmd.Class; ApduBuffer[1] = ApduCmd.Ins; ApduBuffer[2] = ApduCmd.P1; ApduBuffer[3] = ApduCmd.P2; var lengthExpected = ApduCmd.Le; var apduData = TransmitRaw(ApduBuffer, lengthExpected); return(new APDUResponse(apduData)); }
abstract public APDUResponse Transmit(APDUCommand ApduCmd);
public bool authenticate(byte[] key, byte block) { //Load authentication APDUCommand cc1 = new APDUCommand( 0xFF, 0x82, 0x00, 0x00, key, 0x06); try{ APDUResponse rr1 = this.iCard.Transmit(cc1); }catch(System.Exception){ Debug.WriteLine("ACR112_v2:: Transmit Error, " + cc1.ToString()); return false; } //Authenticate APDUCommand cc2 = new APDUCommand(0xFF, 0x86, 0x00, 0x00, new byte[]{0x01,0x00,block,0x60,0x00} , 0x05); try{ APDUResponse rr2 = this.iCard.Transmit(cc2); }catch(System.Exception){ Debug.WriteLine("ACR112_v2:: Transmit Error, " + cc2.ToString()); return false; } return true; }
public void select() { //Make the request byte[] d1 = new byte[9] { 0xD4, 0x60, 0x01, 0x01, 0x20, 0x23, 0x11, 0x04, 0x10}; APDUCommand a1 = new APDUCommand( 0xFF, 0x00, 0x00, 0x00, d1 ,0x09); APDUResponse r1; try{ r1 = this.iCard.Transmit(a1); }catch(System.Exception){ return; } //Retrieve the result APDUCommand a2 = new APDUCommand( 0XFF, 0xC0, 0x00, 0x00, null, r1.SW2); APDUResponse r2; try{ r2 = this.iCard.Transmit(a2); }catch(System.Exception){ return; } int data_len = r2.Data.Length; //Exceptions: No tags found, tag type not mifare (Schema?) Wrong type of tag if(data_len==3){ return; } //Retrieve the UID from the data returned _uid = new byte[4]; Array.Copy( r2.Data,data_len-4, _uid, 0, 4); //Store card information _numCards = r2.Data[2]; _tagType = new Byte[]{ r2.Data[3], r2.Data[4] }; _tag = r2.Data[7]; }
/// <summary> /// Wraps the PCSC function /// LONG SCardTransmit( /// SCARDHANDLE hCard, /// LPCSCARD_I0_REQUEST pioSendPci, /// LPCBYTE pbSendBuffer, /// DWORD cbSendLength, /// LPSCARD_IO_REQUEST pioRecvPci, /// LPBYTE pbRecvBuffer, /// LPDWORD pcbRecvLength /// ); /// </summary> /// <param name="ApduCmd">APDUCommand object with the APDU to send to the card</param> /// <returns>An APDUResponse object with the response from the card</returns> public override APDUResponse Transmit(APDUCommand ApduCmd) { CSCardCmd itfCmd = new CSCardCmdClass(); CByteBuffer itfData = new CByteBufferClass(); int nLe = ApduCmd.Le; if (ApduCmd.Data == null) { itfData.SetSize(0); } else { int nWrite = 0; itfData.SetSize(ApduCmd.Data.Length); itfData.Write(ref ApduCmd.Data[0], ApduCmd.Data.Length, ref nWrite); } // Build the APDU command itfCmd.BuildCmd(ApduCmd.Class, ApduCmd.Ins, ApduCmd.P1, ApduCmd.P2, itfData, ref nLe); // Send the command m_itfCard.Transaction(ref itfCmd); // Analyse the response int nRead = 0; byte[] pbResp = new byte[itfCmd.ApduReplyLength]; itfCmd.ApduReply.Read(ref pbResp[0], itfCmd.ApduReplyLength, ref nRead); return new APDUResponse(pbResp); }
public bool authenticate(byte[] key, byte block) { byte[] card_uid=uid(); if(card_uid==null) { return false; } //Send authentication command byte[] d1 = new byte[] { 0xD4, 0x40, 0x01, 0x60, block, key[0], key[1], key[2], key[3], key[4], key[5], card_uid[0], card_uid[1], card_uid[2], card_uid[3] }; APDUCommand a1 = new APDUCommand( 0xFF, 0x00, 0x00, 0x00, d1, 0x0F); try{ APDUResponse r1 = this.iCard.Transmit(a1); }catch(System.Exception){ return false; } //Status code 61 05 is valid //Read response APDUCommand a2 = new APDUCommand( 0xFF, 0xC0 , 0x00, 0x00, null, 0x05); try{ APDUResponse r2 = this.iCard.Transmit(a2); }catch(System.Exception){ return false; } //Status code 90 00 is valid, else error return true; }
public byte[] readBlock(byte block) { byte[] d1 = new Byte[] { 0xD4, 0x40, 0x01, 0x30, block }; APDUCommand a1 = new APDUCommand( 0xFF, 0x00, 0x00, 0x00, d1, 0x05); try{ APDUResponse r1 = this.iCard.Transmit(a1); }catch(System.Exception){ return null; } //Status code 61 15 APDUCommand a2 = new APDUCommand( 0xFF, 0xC0, 0x00, 0x00, null, 0x15); APDUResponse r2; try{ r2 = this.iCard.Transmit(a2); }catch(System.Exception){ return null; } //Status Code ?? _connected = false; return r2.Data; }
/// <summary> /// Wraps the PCSC function /// LONG SCardTransmit( /// SCARDHANDLE hCard, /// LPCSCARD_I0_REQUEST pioSendPci, /// LPCBYTE pbSendBuffer, /// DWORD cbSendLength, /// LPSCARD_IO_REQUEST pioRecvPci, /// LPBYTE pbRecvBuffer, /// LPDWORD pcbRecvLength /// ); /// </summary> /// <param name="ApduCmd">APDUCommand object with the APDU to send to the card</param> /// <returns>An APDUResponse object with the response from the card</returns> public override APDUResponse Transmit(APDUCommand ApduCmd) { uint RecvLength = (uint) (ApduCmd.Le + APDUResponse.SW_LENGTH); byte[] ApduBuffer = null; byte[] ApduResponse = new byte[ApduCmd.Le + APDUResponse.SW_LENGTH]; SCard_IO_Request ioRequest = new SCard_IO_Request(); ioRequest.m_dwProtocol = m_nProtocol; ioRequest.m_cbPciLength = 8; // Build the command APDU if (ApduCmd.Data == null) { ApduBuffer = new byte[APDUCommand.APDU_MIN_LENGTH + ((ApduCmd.Le != 0) ? 1 : 0)]; if (ApduCmd.Le != 0) ApduBuffer[4] = (byte) ApduCmd.Le; } else { ApduBuffer = new byte[APDUCommand.APDU_MIN_LENGTH + 1 + ApduCmd.Data.Length]; for (int nI = 0; nI < ApduCmd.Data.Length; nI++) ApduBuffer[APDUCommand.APDU_MIN_LENGTH + 1 + nI] = ApduCmd.Data[nI]; ApduBuffer[APDUCommand.APDU_MIN_LENGTH] = (byte) ApduCmd.Data.Length; } ApduBuffer[0] = ApduCmd.Class; ApduBuffer[1] = ApduCmd.Ins; ApduBuffer[2] = ApduCmd.P1; ApduBuffer[3] = ApduCmd.P2; m_nLastError = SCardTransmit(m_hCard, ref ioRequest, ApduBuffer, (uint) ApduBuffer.Length, IntPtr.Zero, ApduResponse, out RecvLength); if (m_nLastError != 0) { string msg = "SCardTransmit error: " + m_nLastError; throw new Exception(msg); } byte[] ApduData = new byte[RecvLength]; for (int nI = 0; nI < RecvLength; nI++) ApduData[nI] = ApduResponse[nI]; return new APDUResponse(ApduData); }
public bool disconnect() { APDUCommand c1 = new APDUCommand(0xFF, 0x00, 0x00, 0x00, new byte[]{0xD4, 0x44, 0x01}, 0x03); APDUResponse r1 = iCard.Transmit(c1); APDUCommand c2 = new APDUCommand(0xFF, 0xC0, 0x00, 0x00, null, 0x05); APDUResponse r2 = iCard.Transmit(c2); this.iCard.Disconnect(DISCONNECT.Reset); _connected = false; return true; }
public byte[] readBlock(byte block) { //Read block APDUCommand cc3 = new APDUCommand(0xFF, 0xB0, 0x00, 0x08, null, 0x10); try{ APDUResponse rr3 = this.iCard.Transmit(cc3); return rr3.Data; }catch(System.Exception){ Debug.WriteLine("ACR112_v2:: Transmit Error, " + cc3.ToString()); return null; } return null; }
public void select() { //Firmware //APDUCommand c_f = new APDUCommand( 0xFF, 0x00, 0x48, 0x00, null, 0x00); //APDUResponse r_f = this.iCard.Transmit(c_f); //Select? APDUCommand cc0 = new APDUCommand( 0xFF, 0xCA, 0x00, 0x00 ,null, 0x04); try{ APDUResponse rr0 = this.iCard.Transmit(cc0); }catch(System.Exception){ Debug.WriteLine("ACR112_v2:: Transmit Error, " + cc0.ToString()); } }
public bool Execute(string LogMessage, APDUCommand Command) { var State = Card.State; // получаем состояние карты - без этого Transmit в realtime выдает ошибку (может быть карта на успевает отработать... Response = Card.Transmit(Command); bool Result = ValidResponse(Response); if (LogMessage.Length > 0) Log.Log(2, LogMessage + " " + (Result ? "success: " + Response.Status.ToString("X") : "failed: " + Response.Status.ToString("X"))); /*if (Response.SW1 == SC_PENDING1 || Response.SW1 == SC_PENDING2) { State = Card.State; GetResponseCommand.Le = Response.SW2; Response = Card.Transmit(GetResponseCommand); Result = ValidResponse(Response); if (LogMessage.Length > 0) Log.Log(3, "GET RESPONSE " + (Result ? "success: " + Response.Status.ToString("X") : "failed: " + Response.Status.ToString("X")) + " Data: "+Functions.ByteArrayToString(Response.Data)); }*/ return Result; }
public void TenAttempts() { const byte KEY_ADM1 = 0x0A; APDUCommand VerifyCommand = new APDUCommand(0x00, 0x20, 0x00, KEY_ADM1, new byte[8], 0x00); if (Execute("Select application", SelectApplicationCommand)) { for (int i = 0; i < 15; i++) { new Random().NextBytes(VerifyCommand.Data); if (Execute("Verify ADM1", VerifyCommand)) { Log.Log(2, "OK"); } else Log.Log(2, "Attempt #{0} failed"); } } }
public bool Personalize(BigInteger CardNumber) { bool Result = false; // генерация уникального ключа карты и административных ключей byte[] UID, ADM1, ADM2; Crypto.GenerateCardCryptography(out UID, out ADM1, out ADM2); byte[] CardNumberBCD = Functions.StringToBCD(CardNumber.ToString()); byte[] CardNumberData = new byte[CardNumberBCD.Length + 1]; // 1 for length CardNumberData[0] = (byte)CardNumberBCD.Length; CardNumberBCD.CopyTo(CardNumberData, 1); /*string cns = Functions.ByteArrayToString(CardNumberData), uids = Functions.ByteArrayToString(UID), adm1s = Functions.ByteArrayToString(ADM1), adm2s = Functions.ByteArrayToString(ADM2);*/ APDUCommand SelectFileCommand = new APDUCommand(0x00, 0xA4, 0x00, 0x00, null, 0x00), UpdateCommand = new APDUCommand(0x00, 0xD6, 0x00, 0x00, null, 0x00), LockCommand = new APDUCommand(0x00, 0xFF, 0x00, 0x00, null, 0x00); if (Execute("Select application", SelectApplicationCommand)) { SelectFileCommand.Data = new byte[] { 0x00, 0x01 }; if (Execute("Select 0001 (ADM1)", SelectFileCommand)) { UpdateCommand.Data = ADM1; if (Execute("Write ADM1 into 0001", UpdateCommand)) { SelectFileCommand.Data = new byte[] { 0x00, 0x02 }; if (Execute("Select 0002 (ADM2)", SelectFileCommand)) { UpdateCommand.Data = ADM2; if (Execute("Write ADM2 into 0002", UpdateCommand)) { SelectFileCommand.Data = new byte[] { 0x2F, 0x00 }; if (Execute("Select 2F00 (UID)", SelectFileCommand)) { UpdateCommand.Data = UID; if (Execute("Write UID into 2F00", UpdateCommand)) { SelectFileCommand.Data = new byte[] { 0x2F, 0x01 }; if (Execute("Select 2F01 (CardNumber)", SelectFileCommand)) { UpdateCommand.Data = CardNumberData; if (Execute("Write CardNumber into 2F01", UpdateCommand)) { if (Execute("Lock the card", LockCommand)) { Result = true; } } } } } } } } } } /* // Чтение карты P+ APDUCommand SelectCommand = new APDUCommand(0x00, 0xA4, 0x00, 0x00, null, 0x00), ReadCommand = new APDUCommand(0x00, 0xB2, 0x01, 0x00, null, 0x06); SelectCommand.Data = new byte[] { 0xA0, 0x06 }; //Log.Log(4, Card.State.ToString()); if (Execute("Select A006", SelectCommand)) { SelectCommand.Data = new byte[] { 0x31, 0x20 }; //Log.Log(4, Card.State.ToString()); if (Execute("Select 3120", SelectCommand)) { ReadCommand.Le = 0x06; //Log.Log(4, Card.State.ToString()); if (Execute("Read from 3120", ReadCommand)) { Log.Log(1, "Data: " + Functions.ByteArrayToString(Response.Data)); Result = true; } } }*/ return Result; }