Java. Lorawan package decription. AES-128

FlySpot:

À première vue, j'ai le même problème que beaucoup. Mais mon cas un peu plus complexe.

Conditions:
Langue du projet: Java 11
Network Server: Orbiwise NS ( https://eu.saas.orbiwise.com/ )
périphérique: connexion (module STM32 + Wifi) via une passerelle lorawan à Orbiwise et en utilisant socket TCP via wifi.

Entrée des données:
A partir de TCP socket reçu tableau d'octets:

40 24 fa fa 01 c2 c5 25  03 06 01 43 a4 99 5a c1
85 71 0c 87 38 84 53 9a  80 6c 5a 14 da f8 ff 7c
21 83 8f 78 8e ec f2 7d  4e 4e 07  

(43 octets)

Sur Orbiwise ont lui correspondant Uplink charge utile:

31 19 10 07 01 13 51 25  09 01 00 00 00 00 33 04
00 00 5A 00 00 00 EB 0D  00 00 64 EB 

(28 octets)

Tâche:
données Déchiffrer Socket TCP pour la charge utile déchiffré dans le même format que sur Orbiwise

Les approches ont été utilisées sans résultat positif:

  1. https://github.com/jsubercaze/javalora
  2. https://github.com/huahang/crypto-utils/blob/master/crypto-utils/src/main/java/im/chic/utils/crypto/AesUtils.java
  3. https://github.com/matthiaszimmermann/ttn_decoder_java - code de base pour le mien.

Tout projet ci - dessus a été écrit il y a longtemps et ne m'a pas aidé. Celui - ci a aidé , mais écrit sur le nœud JS: https://github.com/anthonykirby/lora-packet

De spécification lorawan je suis arrivé que utilisé la "AES/ECB/NoPadding"méthode et mon code actuel ressemble à :

package org.thethingsnetwork.main.java.org.thethingsnetwork.util.security;

import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

public class Crypto {

    /**
     * Decrypts TTN data_raw payload to data according to the TTN REST API.
     * @param pld encrypted message payload from ttn mqtt message
     * @param K the TTN application key 
     * @param IV
     * @return decrypted payload
     * @throws Exception
     */
    public static byte[] decrypt(byte [] pld, byte [] K, byte [] IV) throws Exception {
        byte [] devAddr = getDevAddr(pld);
        byte [] frameCounter = getFrameCounter(pld);
        byte [] result = initializeResult(pld);
        byte [] Ai = new byte[16];
        byte [] Si = null;

        for(int i = 0; i < result.length; i += 16) {
            int blockSeqCnt = (i >> 4) + 1;

            computeAi(Ai, devAddr, frameCounter, blockSeqCnt);

            Si = encryptAES(Ai, K, IV);

            for(int j=0; j < 16 && i+j < result.length; j++) {
                result[i+j] ^= Si[j];
            }
        }
        return  result;
    }

    /**
     * Converts TTN payload data to data_plain according to the TTN REST API.
     * Decode a text using base 64 decoding. 
     * @param decryptedText
     * @return
     */
    public static String toPlainText(String decryptedText) {
        byte [] data = Base64.getDecoder().decode(decryptedText);
        StringBuffer plain = new StringBuffer();

        for(int i = 0; i < data.length; i++) {
            plain.append((char)data[i]);
        }

        return plain.toString();
    }


    public static byte [] getDevAddr(byte [] payload) {
        byte [] devAddr = new byte[4];
        System.arraycopy(payload, 1, devAddr, 0, 4);
        return devAddr;
    }

    public static byte [] getFrameCounter(byte [] payload) {
        byte [] frameCounter = new byte[2];
        System.arraycopy(payload, 6, frameCounter, 0, 2);
        return frameCounter;
    }

    public static byte [] initializeResult(byte [] payload) {
        byte [] result = new byte[payload.length - 13];

        for(int i = 0; i < result.length; i++) {
            result[i] = payload[i+9];
        }

        return result;
    }

    public static void computeAi(byte [] a, byte [] devAddr, byte [] frameCounter, int blockSeqCnt) {
        a[0]  = 0x01;
        a[1]  = 0x00;
        a[2]  = 0x00;
        a[3]  = 0x00;
        a[4]  = 0x00;
        a[5]  = 0;               // 0 for uplink frames 1 for downlink frames;
        a[6]  = devAddr[0];      // LSB devAddr 4 bytes
        a[7]  = devAddr[1];      // ..
        a[8]  = devAddr[2];      // ..
        a[9]  = devAddr[3];      // MSB
        a[10] = frameCounter[0]; // LSB framecounter
        a[11] = frameCounter[1]; // MSB framecounter
        a[12] = 0x00;            // Frame counter upper Bytes
        a[13] = 0x00;
        a[14] = 0x00;
        a[15] = (byte)blockSeqCnt;  // block sequence counter 1,2,3...
    }

    /**
     * AES encrpytion.
     */
    public static byte[] encryptAES(byte [] data, byte [] key, byte [] iv) throws Exception {
        Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding", "SunJCE");
        SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
        cipher.init(Cipher.DECRYPT_MODE, keySpec);
        return cipher.doFinal(data);
    }

}

Et deuxième classe - test:

package org.thethingsnetwork.util.security;

import org.apache.commons.codec.DecoderException;
import org.junit.Assert;
import org.junit.Test;
import org.thethingsnetwork.main.java.org.thethingsnetwork.util.security.Crypto;
import org.apache.commons.codec.binary.Hex;

public class CryptoTest {

private byte [] SEMTECH_DEFAULT_KEY = Hex.decodeHex("2E12E8BD30FE2FB2D8DE609747D2569F".toCharArray());

    public static final byte [] IV = new byte [] {
            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
    };  //  initialization vector – IV

    // example data from a ttn message
    public static final byte[] TEXT_RAW   = new byte[] {0x40, 0x24, (byte) 0xfa, (byte) 0xfa, 0x01, (byte) 0xc2,
            (byte) 0xc5, 0x25, 0x03, 0x06, 0x01, 0x43, (byte) 0xa4, (byte) 0x99, 0x5a, (byte) 0xc1, (byte) 0x85, 0x71,
            0x0c, (byte) 0x87, 0x38, (byte) 0x84, 0x53, (byte) 0x9a, (byte) 0x80, 0x6c, 0x5a, 0x14, (byte) 0xda,
            (byte) 0xf8, (byte) 0xff, 0x7c, 0x21, (byte) 0x83, (byte) 0x8f, 0x78, (byte) 0x8e, (byte) 0xec, (byte) 0xf2,
            0x7d, 0x4e, 0x4e, 0x07};

    public CryptoTest() throws DecoderException {
    }

    @Test
    public void testDecoder() throws Exception {
        byte[] decryptedText = Crypto.decrypt(TEXT_RAW, SEMTECH_DEFAULT_KEY, IV);

        printTheByteToString(decryptedText);
    }

    /**
     * Method for prin in command line byte array. For debug necessary
     * @param b - input byte array
     */
    private void printTheByteToString (byte[] b) {
        for (byte val : b) {
            System.out.print(String.format("%02x ", val));
        }
    }
}

J'ai vérifié le code une centaine de fois, mais aucun résultat positif - le message déchiffré est différent de sur Orbiwise.

J'ai vérifié les données à l' aide projet NodeJS ( https://github.com/anthonykirby/lora-packet ) et tout est correct. Mais ne peut pas résoudre la tâche en utilisant mon code Java.
entrez la description d'image ici

l'aide du corps peut-il me dans cette situation? Merci beaucoup d'avance!

Martin Bodewes:

Votre cryptogramme décalage est désactivée par 2 (il y a 3 octets au lieu de l'option 1, sans doute). L'impression des résultats intermédiaires ou d'effectuer l'analyse complète des octets d'en-tête devrait vous montrer que, ce qui est la raison pour laquelle je l'ai mentionné dans les commentaires. A noter que de plus en plus le décalage de 9 par 2 peut également affecter la taille de texte chiffré, comme la fin du texte chiffré est fixé.

De plus, vous utilisez Cipher.DECRYPT_MODEalors que le protocole utilise uniquement le chiffrement en mode avant. Mode compteur (utilisé par CCM et CCM * chiffrements) utilise uniquement le chiffrement en mode avant qu'ils génèrent un flux clé qui est alors XOR avec le flux de texte brut ou un flux de cryptogramme à Crypter / Décrypter respectivement. La partie « décryptage » dans le protocole est seulement d' environ la réalisation finale de la XOR généré flux de clés pour le texte chiffré plutôt que le texte en clair.

Bien sûr, le mode de la BCE - utilisé pour simplement mettre en œuvre un chiffrement de bloc unique dans ce cas - ne nécessite pas d'IV, de sorte qu'une partie du code est faux.

Je suppose que tu aimes

Origine http://10.200.1.11:23101/article/api/json?id=427946&siteId=1
conseillé
Classement