Java. LoraWan empaquetar decription. AES-128

FlySpot:

A primera vista, tengo el mismo problema que muchos. Pero mi caso un poco más complejo.

Condiciones previas:
el lenguaje del proyecto: Java 11
Servidor de red: Orbiwise NS ( https://eu.saas.orbiwise.com/ )
Dispositivo: (módulo STM32 + Wifi) a través de la conexión Lorawan puerta de entrada a Orbiwise y el uso del socket TCP a través de wifi.

Los datos de entrada:
A partir de Socket TCP recibidos matriz de bytes:

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 bytes)

En Orbiwise haber que le corresponda de enlace ascendente de carga útil:

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 bytes)

Tarea:
descifrar los datos de Socket TCP haber descifrado de carga útil en el mismo formato que en Orbiwise

Métodos se han aplicado sin resultado positivo:

  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 - código del núcleo de la mina.

Todo proyecto anterior fue escrito hace mucho tiempo y no me ayudó. Éste ayudó , pero escrito en el nodo JS: https://github.com/anthonykirby/lora-packet

A partir de la especificación LoraWan Tengo esa usado "AES/ECB/NoPadding"método y mi aspecto de códigos actuales como:

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);
    }

}

Y segunda clase - la prueba:

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));
        }
    }
}

He comprobado el código de un centenar de veces, pero sin resultado positivo - el mensaje descifrado es diferente de la de Orbiwise.

He comprobado los datos utilizando proyecto nodejs ( https://github.com/anthonykirby/lora-packet ) y todo está correcto. Pero no puede resolver la tarea usando mi código Java.
introducir descripción de la imagen aquí

¿Puede algún cuerpo me ayuda en esta situación? ¡Muchas gracias por adelantado!

Martin Bodewes:

Su desplazamiento de texto cifrado está desactivada por 2 (ya que hay 3 bytes en lugar de la opción 1, sin duda). La impresión de los resultados intermedios o la realización de análisis completo de los bytes de cabecera que debería mostrar que, por lo que he mencionado en los comentarios. Nota que el aumento del desplazamiento de 9 por 2 también puede afectar el tamaño de texto cifrado, como el final del texto cifrado es fijo.

Por otra parte, se está utilizando Cipher.DECRYPT_MODE, mientras que el protocolo sólo utiliza el cifrado en modo de avance. El modo de contador (utilizado por CCM y CCM * cifrados) sólo utiliza el sistema de cifrado en el modo de avance, ya que generan un flujo de clave que es entonces XOR-ed con la corriente de texto claro o la corriente de texto cifrado para cifrar / descifrar, respectivamente. La parte "descifrado" en el protocolo sólo se trata de la realización de la XOR final del generado de flujo de clave para el texto cifrado en lugar del texto en claro.

Por supuesto, el modo ECB - se utiliza para implementar simplemente un único bloque de cifrar en este caso - no requiere de una vía intravenosa, por lo que parte del código es espuria.

Supongo que te gusta

Origin http://10.200.1.11:23101/article/api/json?id=427970&siteId=1
Recomendado
Clasificación