How to decrypt the first message sent from Mifare Desfire EV1

后端 未结 2 755
南笙
南笙 2020-12-24 11:31

Does anyone have a clue how to decrypt the first message sent from the card? I mean after the authentication success and then you send a command (for example 0x51 (GetRealTa

2条回答
  •  我在风中等你
    2020-12-24 11:52

    It's not c/c++ section but enter my position, I'm looking at a possible bug from the C developer. I can't proof Java implementation here. But i think @Michael Roland way is not true! Maby! Maby i'm wrong!

    Sry for my English,- its terrible :) but it's not my native language. I'm Russian.

    Check first MSB (7 - bit) of array[0] and then shiffting this to the left. And then XOR if MSB 7 bit was == 1; Or save first MSB bit of array[0] and after shiffting put this bit at the end of array[15] at the end (LSB bit).

    Just proof it's here: https://www.nxp.com/docs/en/application-note/AN10922.pdf

    Try this way:

    Zeros <- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

    SessionKey <- 00 01 02 03 E3 27 64 0C 0C 0D 0E 0F 5C 5D B9 D5

    Data <- 6F 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00

    First u have to encrypt 16 bytes (zeros) with SesionKey;

    enc_aes_128_ecb(Zeros);
    

    And u get EncryptedData.

    EncryptedData <- 3D 08 A2 49 D9 71 58 EA 75 73 18 F2 FA 6A 27 AC

    Check bit 7 [MSB - LSB] of EncryptedData[0] == 1? switch i to true;

     bool i = false;
      if (EncryptedData[0] & 0x80){
        i = true;
      }
    

    Then do Shiffting of all EncryptedData to 1 bit <<.

    ShiftLeft(EncryptedData,16);
    

    And now, when i == true - XOR the last byte [15] with 0x87

    if (i){
        ShiftedEncryptedData[15] ^= 0x87;
      }
    

    7A 11 44 93 B2 E2 B1 D4 EA E6 31 E5 F4 D4 4F 58

    Save it as KEY_1.

    Try bit 7 [MSB - LSB] of ShiftedEncryptedData[0] == 1?

     i = false;
      if (ShiftedEncryptedData[0] & 0x80){
        i = true;
      }
    

    Then do Shiffting of all ShiftedEncryptedData to 1 bit <<.

    ShiftLeft(ShiftedEncryptedData,16);
    

    And now, when i == true - XOR the last byte [15] with 0x87

    if (i){
       ShiftedEncryptedData[15] ^= 0x87;
    }
    

    F4 22 89 27 65 C5 63 A9 D5 CC 63 CB E9 A8 9E B0

    Save it as KEY_2.

    Now we take our Data (6F 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00)

    As Michael say's - pad command with 0x80 0x00...

    XOR Data with KEY_2 - if command was padded, or KEY_1 if don't. If we have more like 16 bytes (32 for example) u have to XOR just last 16 bytes.

    Then encrypt it:

    enc_aes_128_ecb(Data);
    

    Now u have a CMAC.

    CD C0 52 62 6D F6 60 CA 9B C1 09 FF EF 64 1A E3


    Zeros <- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

    SessionKey <- 00 01 02 03 E3 27 64 0C 0C 0D 0E 0F 5C 5D B9 D5

    Key_1 <- 7A 11 44 93 B2 E2 B1 D4 EA E6 31 E5 F4 D4 4F 58

    Key_2 <- F4 22 89 27 65 C5 63 A9 D5 CC 63 CB E9 A8 9E B0

    Data <- 6F 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00

    CMAC <- CD C0 52 62 6D F6 60 CA 9B C1 09 FF EF 64 1A E3

    C/C++ function:

    void ShiftLeft(byte *data, byte dataLen){
      for (int n = 0; n < dataLen - 1; n++) {
       data[n] = ((data[n] << 1) | ((data[n+1] >> 7)&0x01));
      }
      data[dataLen - 1] <<= 1;
    }   
    

    Have a nice day :)

提交回复
热议问题