スマートホームをもう少し安全にする

最近、「スマートホーム」の世界は初心者の愛好家に近づいています。これは、エントリーしきい値が低いハードウェアソリューションが多数存在し(Arduinoプラットフォームとそのためのモジュール/センサーのかなりのセットについて話している)、それらと連携する既製のライブラリとフレームワークがあるためです。 原則として、デフォルト設定(ポピーアドレス、チャネルなど)はそのままで、これらの初心者の手に残ります。たとえば、 Habréでそれほど前に言及されていないMySensorsフレームワークには、設定ファイル「MyConfig.h」があります。多くの人(特に私の不運な隣人)が支配さえしていません。



一方で、多階建ての建物で誰かがキッチンの温度を「盗聴」すること(または「お料理は何ですか?」と質問することもできます)を気にしませんが、一方で、誰にもできることを望みません(ただし、理論的には)電力負荷を管理します(たとえば、お気に入りのコーヒーマシンをオンにします)。 コマンドが偽のデバイスではなく、制御デバイスから送信されることをもう少し確信したいと思います(暗号化では、これは「認証」として知られています)。



このアプローチの実装は比較的簡単です...



コントロールとエグゼクティブデバイス間の相互作用は、両方のデバイスに既知の内部キーを持つランダムフレーズの「署名」に基づいています。 より明確に、これは次のように実証できます。



画像



3つの関数を使用して実装できます。 ランダムなフレーズを生成するための1つ:



byte alphabet[] = { 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a }; // a, b, c, d, etc void getPhrase(byte *phrase) { for (int i = 0; i < 8; i++) { phrase[i] = alphabet[random(0, 26)]; phrase[i + 1] = '\0'; } }
      
      







2つ目は、実際にMD5ハッシュ( ArduinoのMD5ライブラリ)を作成することです。



 #include <MD5.h> byte sessionPhrase[9]; byte salt[] = { 0x4c, 0x39, 0x78, 0x36, 0x73, 0x4c, 0x39, 0x78 }; // L9x6sL9x -   void signPhrase(byte *phrase, char *signedPhrase) { byte localPhrase[17]; for (int i = 0; i < 16; i++) { if (i < 8) localPhrase[i] = salt[i]; else localPhrase[i] = sessionPhrase[i - 8]; localPhrase[i + 1] = '\0'; } unsigned char* hash = MD5::make_hash((char *)localPhrase); char *md5str = MD5::make_digest(hash, 16); for (int i = 0; i < 16; i++) { signedPhrase[i] = md5str[i]; signedPhrase[i + 1] = '\0'; } free(hash); free(md5str); }
      
      







イニシエーターの「署名済み」フレーズとパフォーマーの「自己署名済み」フレーズを調整するための3番目:



 bool compareSignedPhrases(char *signedPhrase) { if (strcmp(signedPhrase, (char *)sessionMD5Phrase) == 0) { return true; } return false; }
      
      







フレーズの生成、その署名と比較をチェックするための短いコード
#include <MySensor.h>

#include <SPI.h>

#include <MD5.h>



#define DEBUG 1



バイトsessionPhrase [9];

char sessionMD5Phrase [17];

バイトソルト[] = {0x4c、0x39、0x78、0x36、0x73、0x4c、0x39、0x78}; // L9x6sL9x-内部キー

バイトアルファベット[] = {0x61、0x62、0x63、0x64、0x65、0x66、0x67、0x68、0x69、0x6a、0x6b、0x6c、0x6d、0x6e、0x6f、0x70、0x71、0x72、0x73、0x74、0x75、0x75、0x75、0x75、0x75、0x75、0x75、0x75、0x75、0x75、0x75、0x75 0x77,0x78,0x79,0x7a}; // a、b、c、dなど



void setup(){

Serial.begin(115200);

}



void loop(){

/ *ランダムフレーズを生成* /

getPhrase(sessionPhrase);

signPhrase(sessionPhrase、sessionMD5Phrase); //さらなる比較のために覚えておいてください



/ *署名します* /

char signedPhrase [17];

signPhrase(sessionPhrase、signedPhrase);



#ifdef DEBUG

Serial.print( "signedPhrase:„);

Serial.println((char *)signedPhrase);

Serial.print(“ copmpare:„);

Serial.println(compareSignedPhrases(signedPhrase));

Serial.println(“”);

#endif



遅延(1000);

}



void getPhrase(バイト*フレーズ){

for(int i = 0; i <8; i ++){

フレーズ[i] =アルファベット[ランダム(0、26)];

フレーズ[i + 1] = '\ 0';

}



#ifdef DEBUG

Serial.print( "sessionPhrase:„);

Serial.println((char *)sessionPhrase);

#endif

}



void signPhrase(バイト*フレーズ、文字* signedPhrase){

バイトcatPhrase [17];

for(int i = 0; i <16; i ++){

if(i <8)catPhrase [i] = salt [i];

それ以外の場合catPhrase [i] = sessionPhrase [i-8];

catPhrase [i + 1] = '\ 0';

}



#ifdef DEBUG

Serial.print(“ catPhrase:„);

Serial.println((char *)catPhrase);

#endif



unsigned char * hash = MD5 :: make_hash((char *)catPhrase);

char * md5str = MD5 :: make_digest(ハッシュ、16);



for(int i = 0; i <16; i ++){

signedPhrase [i] = md5str [i];

signedPhrase [i + 1] = '\ 0';

}



無料(ハッシュ);

無料(md5str);

}



bool compareSignedPhrases(char * signedPhrase){

if(strcmp(signedPhrase、(char *)sessionMD5Phrase)== 0){

trueを返します。

}

falseを返します。

}





このアプローチは、「自転車」と他のフレームワーク(MySensorsなど)の両方で実行でき、モノのインターネットのセキュリティをさらに強化します。



ところで、認証はMySensorsで行われますが、現在は開発バージョンで実装されています。



PS:それがコミュニティにとって興味深い場合、シリアルゲートウェイとリレーのリストの例としてMySensorsを使用してメモを更新します...



All Articles