茱萸note

電子工作の備忘録と旅行の記録

Arduino ESP8266 IoT マイコン 電子工作

ESP8266 で RSA PKCS#1 V1.5 暗号の復号

投稿日:

ESP8266 で RSA 暗号化の方式の一つである RSA PKCS#1 V1.5 、別名 RSAES-PKCS1-v1_5 の暗号を復号する方法です。


目次


別記事で、AES-CBC PKCS#7 Padding の暗号化・復号を ESP8266 で実現しました。

今回は、RSA 暗号化の方式の一つである RSA PKCS#1 V1.5 、別名 RSAES-PKCS1-v1_5 の暗号の復号を ESP8266 で試します。前回同様、ESP8266 の SDK に付属している BearSSL を利用して実装します。

RSA 暗号化の2つの方式

RSA アルゴリズムでの暗号化には2つの方式があります。

後者の RSAES-PKCS1-v1_5 は古い方式とされており、前者の RSAES-OAEP 方式が推奨されています。しかしこの度、RSAES-PKCS1-v1_5 の復号を実装する機会があったので、その方法を簡単に紹介する運びとなりました。

PKCS#1 V1.5 の名が付くスキームは、他にも RSASSA-PKCS1-v1_5EMSA-PKCS1-v1_5 がありますが、これらは証明書の署名に関するスキームであり、今回扱う暗号化スキーム RSAES-PKCS1-v1_5 とは異なります。

RSA PKCS1 V1.5 暗号の復号

先にプログラムを示します。このプログラムは事前に公開鍵を送信したサーバーから暗号文が届き、それを秘密鍵で復号するという想定で書いています。

const char rsa_private_key[] = R"EOF(
-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----
)EOF";

const char rsa_public_key[] = R"EOF(
-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----
)EOF";

// Input : data
uint8_t data[] = {...};
int len = sizeof(data);

// RSA PKCS#1 V1.5 Decryption
BearSSL::PrivateKey *private_key = new BearSSL::PrivateKey(rsa_private_key);

(*br_rsa_private_get_default())(data, private_key->getRSA());

int i;
for(i = 2; i < len; i++){
  if(data[i] == 0) break;
}
i++;

len -= i;
uint8_t decoded_data[len];
memcpy(decoded_data, &data[i], len);

// Output : Decoded data
// return decoded_data;

プログラムの説明

鍵を PEM 形式で書きます。ESP8266 に鍵のペアを生成させるのは難しい気がするので、鍵の生成は openssl などで事前に済ませておきます。

const char rsa_private_key[] = R"EOF(
-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----
)EOF";

鍵は ESP8266 Arduino ライブラリの BearSSL::PrivateKey クラスにブチ込みます。

BearSSL::PrivateKey *private_key = new BearSSL::PrivateKey(rsa_private_key);

暗号は次で復号します。復号文は暗号を格納していた data に書かれます。

(*br_rsa_private_get_default())(data, private_key->getRSA());

次は、PKCS#1 V1.5 Padding の処理です。復号文から元の平文を抽出します。

RSAES-PKCS1-v1_5 では、復号文は 00 02 から始まります。そして、平文は、次に 00 が現れたらその次のバイトから始まります。要するに、復号文は 00 02 <ゴミ(00を含まない)> 00 <平文> という形式になっています。

int i;
for(i = 2; i < len; i++){
  if(data[i] == 0) break;
}
i++;

len -= i;
uint8_t decoded_data[len];
memcpy(decoded_data, &data[i], len);

-電子工作
-, , , ,


comment

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

関連記事

Alexa で ESP8266 を制御する ―― プログラムの解説編【Alexa×Arduino その3】

Alexa で ESP8266 を制御するプログラムの解説です。

Online Storageの画像を貼る

Online Storage上にアップロードした画像をBlog等に貼る方法を考察します。

【Ubuntu】【上級者向け】Grubブートローダをインストールする

「EFIシステムパーティションを新たに作成した」などの理由でGrubブートローダをインストールしたい人に向けてその方法を説明します。

Alexa で ESP8266 を操作する方法【Alexa×Arduino 検討】

Alexa を搭載した Amazon Echo 等を使って ESP8266(Arduino)を操作する方法を検討します。

【Ubuntu】【Python】virtualenvを使う

UbuntuでPythonのパッケージ管理をしやすくするためにvirtualenvを導入します。