2017-09-26 3 views
1

blueoothモジュールで暗号化されたテストデータの一部を解読しようとしています。 BluetoothのファームウェアはC言語でプログラムされています。Java/Android - 4バイトのMICでAES/CCMを解読する

暗号化されたデータました:

// Test Bytes - 16 bytes 
byte[] testInput = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 
        0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}; 

// Test key - 16 bytes, 128-bit 
byte[] keyBytes = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 
        0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}; 

// Test nonce - 13 bytes, 104-bit 
byte[] nonce = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09, 
       0x0a,0x0b,0x0c}; 

ここで問題があります。 AES/CCMを使用してCのデータを暗号化すると、4バイトのMICを持つ16バイトの出力が生成されます。 JavaでAES/CCM/NoPaddingを使用してデータを暗号化すると、出力も16バイトになりますが、8バイトのMACがあります。 MACとMICという用語はあいまいですが、MICがBluetoothの用語に使用されているようです。

上記のtestInputをJavaで暗号化すると、Cプログラミングの暗号化と同じ16バイトの出力が得られます。しかし、MICとMACの長さが異なるため、どちらの側でもデータを復号化できません。

解決方法はありますか?

私は私のJavaコードを追加しました:

以下
Cipher cipher = Cipher.getInstance("AES/CCM/NoPadding", "BC"); 
SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES"); 
IvParameterSpec ivParameterSpec = new IvParameterSpec(nonce); 
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec); 
byte[] encrypted = cipher.doFinal(testInput); 

// The first 16 bytes print out equivalently with the C-language AES/CCM 

は私の出力の画像です:

以下

enter image description here

はC出力のイメージです。

enter image description here

BLE広告パケット

enter image description here

+1

ブルートゥースの場合、MICは3つの追加バイト、つまり0x00,0x01、およびPDUヘッダーの最初のバイトから計算されるバイトで計算されます。このバイトがなければ、同じMICを得ることはできません。 –

+0

@JamesKPolkどのようにデータを渡すことをお勧めしますか?私は数日間の解決策を探してきました。あなたが私をさらに助けてくれればとっても感謝しています。 – FoxDonut

+1

まず、MICの生成方法を把握しなければなりません。 –

答えて

1

次のJavaコードは、Cコードと同じ出力を生成します:

import org.bouncycastle.jce.provider.BouncyCastleProvider; 

import javax.crypto.Cipher; 
import javax.crypto.spec.GCMParameterSpec; 
import javax.crypto.spec.SecretKeySpec; 
import javax.xml.bind.DatatypeConverter; 
import java.security.Security; 

public class Main { 

    // Test Bytes - 16 bytes 
    static byte[] testInput = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 
      0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}; 

    // Test key - 16 bytes, 128-bit 
    static byte[] keyBytes = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 
      0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}; 

    // Test nonce - 13 bytes, 104-bit 
    static byte[] nonce = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 
      0x0a, 0x0b, 0x0c}; 


    public static void main(String[] args) throws Exception { 
     Security.addProvider(new BouncyCastleProvider()); 
     GCMParameterSpec parameterSpec = new GCMParameterSpec(32, nonce); 
     Cipher cipher = Cipher.getInstance("AES/CCM/NoPadding"); 
     SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES"); 
     cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, parameterSpec); 
     cipher.updateAAD(new byte[]{0x01}); 
     System.out.println(DatatypeConverter.printHexBinary(cipher.doFinal(testInput))); 
    } 
} 

しかし、私はどのようにわかりませんCipher.updateAAD()に提供するバイトを見つける。試行錯誤により0x01が見つかりました。 Bluetooth 4.0仕様を読み込もうとするとかなり苦しいです。スペックは、バイトがパケットヘッダーの最初のバイトであり、3つのビット(NESN、SN、MD)がゼロに強制されていると考えられます。残りのビット私はまだ把握しようとしています。

+0

0x01は今回のヘッダーの最初のバイトですが、これが常にそうであると仮定していますか? – FoxDonut

+0

@FoxDonut:いいえ、3つの可能な値、1、2、3があると思いますが、仕様はかなり混乱しています。ヘッダーにアクセスできますか? –

+0

私のエンジニアはコードのC部分を管理しています。ヘッダーのためにできることは何でも私に送って欲しい。私が特に求めなければならないものは何ですか? – FoxDonut

関連する問題