カテゴリー「電子処方せん」の6件の記事

2022年8月25日 (木)

電子処方せん 基本的な構成

電子処方せんはXML文書であって「XAdES(XML Advanced Electronic Signatures)形式」の長期署名プロファイルで電子署名を施した文書形式です。

「XAdES」フォーマットは、ETSI TS 101 903で定義されたフォーマットです。

規格書だけでは具体的なイメージがなかなか掴めなかったのですが、ONSからサンプルが提供されましたので、早速それを解析してみました。なお、提供された文書を簡単な検証アプリをプラグラムして検証したところ問題なく検証できました。

 

署名対象

以下の図は署名対象を解析したものです。

3つのブロックを署名対象としています。
  1、処方せんデータ
  2、署名者の電子証明書
  3、object要素内のSignedPropertes要素(署名者の情報や署名時刻が記録されている部分)

署名対象は<SignedInfo>要素の中にまとめられています。それぞれのブロックは指定された形式でダイジェスト化され、ハッシュ値が計算されてそれがブロックごとに記録されています。

どのブロックをどのように処理するかは、<xs:Reference>要素に記述されています。3つのブロックがあるので、<xs:Reference>要素も3つあります。ブロックの指定は<xs:Reference>タグの「URI」属性でIDを使って指定します。

<xs:Transforms>で正規化方法を<xs:DigestMethod>でダイジェストを求めるアルゴリズムを指定します。

ダイジェスト処理で得られたハッシュ値は<xs:DigestValue>に記述します。

Untitled-58

 

電子署名

電子署名は、ハッシュが記録された「SignedInfo」要素を指定された形式に正規化し、指定された形式のハッシュを求め、それを署名者の秘密鍵で暗号化して「SignatureValue」要素内に記録します。

Untitled-59

 

以上

 


歯科電子カルテシステム・カルテメーカー は利用料月額16,500円(税込)
MacとWinの両方で利用可能な電子カルテです。介護保険にも対応してます。

カルテメーカーの詳細はカルテメーカー・ホームページまで。
カルテメーカーを実際に動かしてみたいときは評価版をダウンロードできます。

 

| | コメント (9)

2022年8月12日 (金)

電子処方せん対応 4Dプラグイン開発(その3かな?)

4Dのプラグインを開発する

OpenSSL、PKCS#11を使った4Dのプラグインを開発する時の備忘録

4D Plugin WizardでVisual Studioのプロジェクトを作る

4D Plugin Wizard.4DProjectを4D.exeで起動

Newボタンで新しいプロジェクトを追加、名前をつけて開く

49_20220812175001

Add Theme...で新しいテーマを追加

Add Command...で新しいコマンド(関数)を追加

48_20220812175301

コマンドの名前を決めて

Addボタンで引数を追加、タイプ、名前、方向を決める。戻り値のある無し、型も指定、OKで保存

コマンドは後でいくらでも追加、修正ができるので、とりあえず適当に一つ作っておけばいい

49_20220812175701

ここのチェックはデフォルトのまま。唯一、Xcodeのプロジェクトは今回は必要ないので、チェックを外しておく

Generateボタンを押してプロジェクトを生成、保存先フォルダを指定して保存

ランタイムエラーがでるが、無視して継続を選んで最後まで実行、プロジェクト名のフォルダができてその内容が表示される。

51_20220812180801

4D Plugin-VS.slnがプロジェクトファイルだ

プロジェクトの起動とビルド

4D Plugin-VS.slnをダブルクリックするとVisual Studioが起動する、4Dが生成したプロジェクトは古いので最新のバージョンになるようにOKボタンを押して自動的に変換してもらう。

52_20220812182101

起動した。ソリューションエクスプローラーからソースファイルの4DPlugin.cppを選択するとソースが表示される。

53

ソースは不完全なので、このままではコンパイルできない。試しにビルドするとエラーが吐き出されるのでソースを修正する。4Dのプラグインは4DのAPIを使って引数を取り出し、4DのAPIで引数にデータを戻す。文字列(ストリング)はUTF16なのでunsigned short*であるので、ストリング関係の関数は2バイト用のを使うこと。ストリングリテラルはL"abc"という感じ。ストリングの受け渡しは少々わかりづらいので注意。BLOBはハンドルで渡される。ハンドルのロック、アンロックに注意。そのあたりを注意しておけば大丈夫だ。

詳細は省くが、こんな感じのソースにするとビルドできる。

void HPKI_test( PA_PluginParameters params )
{
	PA_long32 Param1;
	PA_Unistring* Param2;
	PA_Unichar* Param2_uchars;
	PA_Handle Param3;

	Param1 = PA_GetLongParameter(params, 1);
	Param2 = PA_GetStringParameter( params, 2 );
	Param2_uchars = PA_GetUnistring(Param2);

	Param2_uchars = (PA_Unichar * )L"789";
	Param3 = PA_GetBlobHandleParameter(params, 3);


	// --- write the code of HPKI_test here...
	PA_SetLongParameter( params, 1, Param1 );
	PA_SetUnistring( Param2, Param2_uchars );
	PA_SetBlobHandleParameter( params, 3, Param3 );
}

 

ビルドするとsample.4Dbase→Pluginsフォルダの中に4D Plugin.bundleというプラグインができる。

sample.4Dbaseフォルダ中にはsample.4dbという4Dのデータベースが最初からあるので、これを起動すると作ったプラグインが表示されて利用可能になる。

56_20220812193301

あとは適当にテストメソッドを書いてテストする。

57_20220812193701

テスト→修正を繰り返す時は、必ず4Dを終了させること。動いているとプラグインが開いたままなので、VisualStudioからプラグインを書き換えられないのでリンクエラーとなる。

 

プラグインのコマンドの追加

 

コマンドの追加はResources¥manifest.jsonを修正する。ダブルクリックするとVSが開くので、追加するコマンドを表現したjsonオブジェクトをコレクションに追加する。

58

 

プラグインのソースの先頭のスイッチ文に新しいコマンドの関数への分岐を追加する。

59

 

関数を実装する。

61_20220812204601

 

4DPlugin.hヘッダーファイルで新しい関数を宣言する。

69_20220812210701

 

OpenSSL、PKCS#11の導入

次にOpenSSLとPKCS#11を使えるようにプロジェクトの設定を変更する。

 

ソースにインクルードファイルを記述、HPKIのサンプルコードのソースからコピペ

62_20220812213701

 

OpenSSLのインクルードファイルまでのパスを追加する。

63_20220812211101

 

pkcs11.hヘッダーファイルをHPKIのサンプルコードのフォルダからプラグインのフォルダにコピーする。

67_20220812211401

 

pkcs11.hヘッダーファイルは、置いただけでは認識されないので、プロジェクトにドラッグ&ドロップする。

70

 

プロジェクト→右クリック→プロパティで、リンカーの入力。追加の依存ファイルにlibcrypto.libを追加

71

 

同じくリンカーの全般の追加のライブラリディレクトリにC:¥Program Files¥OpenSSL-Win64¥libを追加

72

 

以上で終わりかな。漏れてたらあとで追記する。あとはひたすら書いて直す書いて直す...楽しい苦行のはじまりだ。

 


歯科電子カルテシステム・カルテメーカー は利用料月額16,500円(税込)
MacとWinの両方で利用可能な電子カルテです。介護保険にも対応してます。

カルテメーカーの詳細はカルテメーカー・ホームページまで。
カルテメーカーを実際に動かしてみたいときは評価版をダウンロードできます。

 

| | コメント (0)

電子処方せん対応 4Dプラグイン開発

電子処方箋対応 4Dプラグイン開発 pkcs#11、OpenSSL、電子署名、HPKIカード 導入備忘録」の続き

 

サンプルコードのテスト

以下のページの「サンプルコード(ZIP形式)」をクリックしてzipファイルをダウンロード

やさしいHPKIMeDis

サンプルのコマンドを使ってみる

サンプルの中にビルド済みの実行ファイルがあるので、これを使ってみる。使い方は付属ドキュメントを参照

適当なところに「すべて展開..」で解凍する。

27_20220812155001

「HPKISignVerifySamoleP11」フォルダを開く

28_20220812155301

「HPKISignVerifySamoleP11.exe」を確認

HPKIカードをセットして、コマンドプロンプトを開いて実行

>HPKISignVerifySampleP11 sign <パスワード>
証明書取得処理 開始
Certificate:
30 82 05 7b 30 82 04 63 a0 03 02 01 02 02 02 01
81 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00
(略)
6b 61 31 1b 30 19 06 03 55 04 05 13 12 54 65 73
...
証明書取得処理 成功: HPKI END ENTITY CERTIFICATE

署名処理 開始
SHA256 HASH:
af a2 7b 44 d4 3b 02 a9 fe a4 1d 13 ce dc 2e 40
16 cf cf 87 c5 db f9 90 e5 93 66 9a a8 ce 28 6d

Signature:
3a e0 63 c6 24 5e 87 42 4b f3 02 7b e7 41 a9 23
7f be 63 c6 18 9b b8 8a 77 80 a2 6c d4 fd 13 b0
(略)
00 ba c8 c3 41 9a 5b bd de a4 7f f8 d0 95 e5 3d
署名処理 成功

検証処理 開始
検証処理 成功

ドライバやライブラリが正しくインストールされていれば、特に問題なく動作する。

 

サンプルのコンパイルとビルド

次に「HPKISignVerifySampleP11」のプロジェクトを開いて、ソースコードの確認とビルドまたはデバッグをしてみる

29_20220812161101

「HPKISignVerifySampleP11.sln」がVSのプロジェクトファイルだ。これをダブルクリックして開く、右のソリューションエクスプローラーで「HPKISignVerifySampleP11.c」をクリックするとソースが表示される。

32_20220812161701

ビルド」メニューから「HPKISignVerifySampleP11をビルド」を選ぶとコンパイルとビルドが開始される。

33_20220812162601

下のパネルに処理経過が表示され、ビルド:成功1と表示されたらOK

今のディレクトリからx64→Debugと開くとビルドしたHPKISignVerifySampleP11.exeができている。

41_20220812163101

コマンドプロンプトで作業ディレクトリをここに変更して、このHPKISignVerifySampleP11.exeを先ほどと同じように実行すると同じ結果が表示される。

ビルドに失敗する時

OpenSSLを標準的な場所のインストールしてあれば問題なくビルドできるはずだ、ダメな時は、ソリューションエクスプローラーでプロジェクト名(HPKISignVerifySampleP11)を右クリック、一番下のプロパティを選択

C/C++の全般の追加のインクルードディレクトリでOpenSSLへのパスを確認

42_20220812163901

リンカの全般の追加のライブラリディレクトリでOpenSSLへのパスを確認

43_20220812164301

同じくリンカのすべてのオプションの追加のライブラリディレクトリOpenSSLへのパスを確認

44_20220812164501

これらが問題なければ、正常にビルドできるはずである。再度ビルドするときは「リビルド」を選ぶ

 

デバッグして処理の追跡する

動作を逐次確認するのであればデバッグモードで動かす。

前準備として、コマンドに渡す引数を事前に設定しておく

ソリューションエクスプローラーでプロジェクト名(HPKISignVerifySampleP11)を右クリック、一番下のプロパティを選択

デバッグのコマンド引数を編集して引数を設定する。先頭のスペースはいらない

45_20220812165201

ソースコードの左端をクリックしてブレークポイントを設定

デバッグメニューからデバッグの開始を選択。

46_20220812165801

ブレークポイントに達すると止まる。変数など確認して動作を見ていく

47_20220812165901

 

以上

 


歯科電子カルテシステム・カルテメーカー は利用料月額16,500円(税込)
MacとWinの両方で利用可能な電子カルテです。介護保険にも対応してます。

カルテメーカーの詳細はカルテメーカー・ホームページまで。
カルテメーカーを実際に動かしてみたいときは評価版をダウンロードできます。

 

| | コメント (0)

忘れないうちにOpenSSLでの暗号化と復号 (その2)

前回の続き、こちらのページを参考にした。

OpenSSL で RSA 公開鍵暗号を試してみようWEB ARCH LABO

公開鍵で暗号化→秘密鍵で復号(通信等)

最初はSSL(TSL)で使われ一般的に通信の暗号化で使われる公開鍵で暗号化→秘密鍵で復号する方法をやってみる

暗号化

openssl-rsautl」コマンドで、文章を暗号化する。「-encrypt」で暗号化を指示、「-pubin」で暗号化を公開鍵で行うように指定、「-inkey」で公開鍵ファイルを指定、「-out」で暗号化した文書の保存先を指定。

$ echo "Hello World" | openssl rsautl -encrypt -pubin -inkey pub.key -out message.dat
$

 

暗号化されたメッセージを見てみる。

$ hexdump message.dat
0000000 84 d2 5d 29 aa ff 3f ce 78 b7 33 6c 23 90 f1 9d
0000010 e4 f0 2f 9c 82 cc 31 02 00 12 48 4b 90 ef 0d f5
0000020 c0 06 bd 59 d4 ed 13 06 5c 2c 6c 04 96 d0 80 0a
0000030 e7 43 4d 0e e0 bc b4 59 a6 70 1a 3c 05 74 74 b4
0000040 2e 3a 35 51 4a 67 4d 62 ab 81 52 c9 12 1d cd 47
0000050 de ef a6 10 a2 f4 9c fe d7 51 86 cd 95 aa 79 a2
0000060 e8 13 5e 7b 13 d2 bf b8 3a 1f 7e 01 55 30 5f 71
0000070 b0 aa 07 cd 74 14 e2 d7 a5 8b 14 16 b5 e3 c3 37
0000080 73 4f 5e b3 0f 50 15 e6 6d 77 61 37 47 83 9c 4b
0000090 52 3b ca c8 09 b3 81 d7 e2 c1 d4 b3 e6 8a 62 db
00000a0 65 81 26 d2 7d 08 60 44 c8 fa e0 9d b3 02 77 56
00000b0 d2 65 f7 14 e4 f2 c2 45 49 ea b4 7d a3 56 78 5f
00000c0 62 f1 2b ab 3f 7d 66 9c de 1f 3a 56 98 76 05 dc
00000d0 4c 31 80 42 65 c0 d2 c7 43 3d b6 34 ba 04 0e 30
00000e0 65 51 f5 16 a5 4b 7d 86 73 30 e1 34 e8 59 b8 2e
00000f0 f8 24 72 9d 1e 5a 84 0e c1 76 d4 c2 62
00000fd

253バイトのバイナリーデータである。鍵長と同じであることに注目。実はこれも1個のでかい整数である。RSA公開鍵では、最終的に公開鍵の数値で割った時の余りが暗号文となるので、必ず桁数は同じになる。ちなみに暗号化前の前処理で平文はパディングという詰め物をして鍵長と同じ桁数の整数にしてから暗号化を行う。パディングについては後述。

また、桁数が決まっているため、一度に暗号化できるのは桁数以下(パディングあるのでもっと短い)の文字数(サイズ)でなければいけない。その上、RSA暗号鍵方式は暗号化、復号化にとても時間がかかるので通常の通信で本文を暗号化するのには向いていない。なので、RSA暗号鍵は、電子署名とか認証という用途(暗号化対象は短くてよい、公開鍵と秘密鍵という2つの鍵が必要)に使われる。

 

復号

復号も同じ「openssl-rsautl」コマンドで行う。「-decrypt」で復号を指示、「-in」で暗号化されたファイルを指定、「-inkey」で秘密鍵を指定、なおデフォルトで扱う鍵は秘密鍵なので、秘密鍵のオプションは必要ない。

$ openssl rsautl -decrypt -in message.dat -inkey server.key
Hello World

無事に復号できた。

 

どんな計算をしてるの?

暗号化、復号の計算は実はとてもシンプル

m:元メッセージ c:暗号文 e:公開指数 n:公開鍵 d:秘密鍵(秘密指数)正確には微妙に違うけどw

20220812-104759

計算式自体は暗号化も復号も全く同一、なので、正確には
秘密鍵で暗号化して、公開鍵でそれを暗号化すると、元の平文になる。
公開鍵で暗号化して、秘密鍵でそれを暗号化すると、元の平文になる。
というわけで、暗号化しかしていない。これは面白い。

ちなみにn=p x qでpとqはでかい素数。dはこのpとqのペアがわからないと計算できない。このnの素因数分解が異常に難しいので安全とされているが、段々難しくなっているようで最近は違う数学的な手法が使われることが多くなってる

なお計算式は簡単であるが、実際の処理は大変である、公開鍵での暗号化でも、公開指数は65537に固定されているけど、253バイト(10進で300桁以上の数値)の6537乗を求めるのもそこそこ大変(msまではかからないけど)秘密鍵に至っては10進300桁の数値の300桁の数値の乗数を計算するのであるから、まともに計算してたら秒単位(コンピュータの世界では永遠に近い時間w)かかってしまうかもしれない。でも、天才は世の中にいるので、数msで処理する計算法を編み出した人がいる。「中国の剰余定理」という方法の応用だ。そしてなんと、この定理の最初の記述は中国の南北朝時代の3~5世紀頃に書かれた「孫子算経」だ。古代中国恐るべし

RSA鍵の計算については前出のこのサイトを参照

RSA鍵の要素と暗号化Qiita

ちょっと脱線。SSL(TSL)のネゴシエーションの時など、サーバー側から適当な乱数をクライアントの公開鍵で暗号化してクライアントに送り、クライアントはそれを自身の秘密鍵で復号する。この平文をサーバーに送ることで、クライアントが正しく証明書の保有者であると確認するのだが、この時、悪意あるサーバーが、文書のハッシュの平文を、暗号化せずにクライアントに送るとどうなるだろう。

クライアントは「秘密鍵で復号する」わけであるが、これは上記のように「秘密鍵で暗号化する」のと同義である。そう、「ハッシュを秘密鍵で暗号化したのが電子署名」であるので、悪意あるサーバーはクライアントが気がつかないうちにクライアントの電子署名がついた文書を入手できてしまうのである。

これを防止するのも先程ちょと触れたパディングである。送る平文に特定のマークをつけてから暗号化する。復号した時にこのマーク(パディング)があれば暗号化されたものだし、なければ、送ってきたのは暗号がされてない平文であると区別できる。パディングについて詳しくは以下のサイトを参照

公開鍵暗号の概要シニアエンジニアの庵 RSA暗号wiki

 

秘密鍵で暗号化→公開鍵で復号(署名のはず)

反対方向も同じなんだから、同じようにOpenSSLを使えばできるんじゃね。ってことで試してみた。

$ echo "Hello World" | openssl rsautl -encrypt -inkey server.key -out messageB.dat
$

おっ、なんかできたっぽい。

 

暗号文の中身を見てみる

$ hexdump messageB.dat
0000000 59 04 86 6f 2e 21 cb e2 79 91 6a b4 f0 2f 49 94
0000010 7d 3a 2c 8c 1b 39 e2 7c a6 fb 8d 7d 52 a4 55 ad
0000020 95 51 5e 86 0c 3c 34 ff d7 53 8e 75 6c 6b f5 fa
0000030 05 a0 fa 78 25 76 0d a2 d2 93 cc 90 cf e6 e4 09
0000040 2a 5c 77 ea 2b cd 49 b3 ea f3 b8 31 85 4e e5 27
0000050 44 36 82 6f 93 9d 72 c1 bc dc 94 9e 5d e5 f6 b7
0000060 10 ad d2 17 09 03 72 24 45 06 39 8a 30 f7 ee 35
0000070 11 6f 5f 7a 56 3f fc 98 f3 5e fa fb 6c 6c 67 ab
0000080 b6 6c 21 50 e8 04 2b 57 d0 33 67 0f 97 f4 7c eb
0000090 0b 78 63 3f ab a2 03 be 2a 00 cd b9 e7 1a 50 af
00000a0 0b a7 a9 0b 00 ab 17 ee 4a 58 eb 78 86 c9 8a 9a
00000b0 62 b2 81 3a bc ec a4 9d 7f 90 0f 13 e1 ac f7 62
00000c0 b8 d3 9b 75 c6 3e cb 54 14 d5 8c 7d fc 28 db 71
00000d0 7f b1 c8 31 f0 a3 a7 88 41 61 36 84 d2 4c d5 db
00000e0 9d 67 b6 92 4e ba 2a 3f 9a 95 c9 46 08 99 4b ae
00000f0 bd 86 20 cb ad 75 ba af d1 7e 55 eb c6
00000fd

それっぽいのができてる

 

公開鍵で復号してみる

$ openssl rsautl -decrypt -in messageB.dat -pubin -inkey pub.key
A private key is needed for this operation

秘密鍵が必要だゴラァって怒られた。なんで?!

 

秘密鍵でやってみる

$ openssl rsautl -decrypt -in messageB.dat -inkey server.key
Hello World

今度はできた。でもこれじゃない(笑)
やりたいのは公開鍵で復号することだ!

 

う〜ん、何故だと探すこと小一時間、これだこれだ

opensslでの暗号化・復号操作@IT

フムフムなるほど、秘密鍵で暗号化→公開鍵で復号は電子署名なので、「-encrypt」と「-decrypt」じゃなくて「-sign」と「-verify」なのね。前出のパディングの関係かなにかで実装する場合は対称ってわけじゃないんだね

 

では、早速やってみよう!

「-sign」オプションをつけて署名を指示、出力ファイル名も変えてと、秘密鍵を使うのでオプションの指定はなしで実行

$ echo "Hello World" | openssl rsautl -sign -inkey server.key -out Esign.dat
$

できた。

 

中身をみる

$ hexdump Esign.dat
0000000 33 f2 5c 05 e0 ab 43 8c 15 47 ae ee cd ef 01 fb
0000010 5c c7 1f 07 bf 1a 7d 43 cf cd 7e 84 26 49 43 01
0000020 90 97 1b 7e 20 d2 9f 27 92 11 8b 80 71 8c 11 c9
0000030 11 1f 5b 2a 26 51 2e 2c ad 10 1e 3a b7 c3 bc aa
0000040 0d b1 f8 01 53 a5 ac 55 d2 e2 6f c1 14 c5 d5 8d
0000050 eb e4 2c f7 dd 03 a4 94 e5 22 8c 58 2d 5c ed c8
0000060 de 63 b1 f5 71 c2 ae 82 ae b3 65 d4 3b e1 6e bd
0000070 00 75 af f6 b0 5a 54 77 36 67 28 df c1 da 6f 5e
0000080 e2 da 30 1a 7c 05 7b 12 bd 47 8b af da f3 b5 f6
0000090 2c 8d c7 51 86 20 66 71 c4 10 7e 98 10 80 68 d8
00000a0 dd 01 fb 76 06 88 ec 20 08 05 6e 89 e9 9f 85 5e
00000b0 a7 2f d9 13 e2 62 83 fa f4 37 c2 76 b3 66 9d db
00000c0 04 b5 c3 7f 92 c8 9d dc bd 70 89 07 48 05 dd 72
00000d0 eb cd e1 2f ea 91 0c c7 ba cd bf 71 04 32 cd a2
00000e0 f4 52 cd b5 fa 25 73 9b 66 62 1b 89 84 23 cc b7
00000f0 b7 7c a7 a7 a1 52 5b 87 26 f3 2c c8 e7
00000fd

できた。あれ、さっきと違う、やっぱりパディングの関係かも。

 

公開鍵で検証(復号)。「-verify」オプションで検証を指示。「-pubin」で公開鍵を使うこと指定

$ openssl rsautl -verify -in Esign.dat -pubin -inkey pub.key
Hello World

正しく復号された!
verify(検証)といいつつ、ここは実際の処理は検証でなく復号なのね(笑)

 

ちなみに秘密鍵でも検証できる。

$ openssl rsautl -verify -in Esign.dat -inkey server.key
Hello World

こんな感じ。秘密鍵に公開鍵が隠れてるからできるのだろう。

 

じゃってことで、上記で-encrypt で暗号化したのを試してみる

$ openssl rsautl -verify -in messageB.dat -pubin -inkey pub.key
RSA operation error
4483001792:error:0407008A:rsa routines:RSA_padding_check_PKCS1_type_1:invalid padding:crypto/rsa/rsa_pk1.c:67:
4483001792:error:04067072:rsa routines:rsa_ossl_public_decrypt:padding check failed:crypto/rsa/rsa_ossl.c:588:

できなかったorz

あっ、でも、やっぱりパディングのエラーだね。暗号化と署名でパディングの形式が違うんだ。なんかスッキリ

 

OpenSSLライブラリではどうなってるのか

RSA暗号鍵での暗号化と復号は、 「RSA_public_encrypt()、RSA_private_decrypt()」で処理する。

 int RSA_public_encrypt(int flen, const unsigned char *from,
                        unsigned char *to, RSA *rsa, int padding);

 int RSA_private_decrypt(int flen, const unsigned char *from,
                         unsigned char *to, RSA *rsa, int padding);

関数名が示すように暗号化は公開鍵で、復号は秘密鍵でしかできない。

 

RSA暗号鍵での署名と検証は、 「RSA_sign()、RSA_verify()」で処理する。

 int RSA_sign(int type, const unsigned char *m, unsigned int m_len,
              unsigned char *sigret, unsigned int *siglen, RSA *rsa);

 int RSA_verify(int type, const unsigned char *m, unsigned int m_len,
                unsigned char *sigbuf, unsigned int siglen, RSA *rsa);

リンク先の説明のとおり、RSA_signは秘密鍵、RSA_verifyには公開鍵を渡す。

コマンドライン での実行と違って、検証は検証だ。RSA_verifyに署名と署名の元となったハッシュを渡すと、それが正しいかどうかを検証して結果をint(1なら検証成功)で返す。復号された平文(ハッシュ値)が返ってくるのではないことに注意

HPKIカードで署名を行う場合は、署名はカード内のアプリケーションが行うのでOpenSSLは使用しない。検証はカードから取り出した証明書とOpenSSLのRSA_verifyでおこなう

 

OpenSSLでの暗号化と復号の話は以上

 


歯科電子カルテシステム・カルテメーカー は利用料月額16,500円(税込)
MacとWinの両方で利用可能な電子カルテです。介護保険にも対応してます。

カルテメーカーの詳細はカルテメーカー・ホームページまで。
カルテメーカーを実際に動かしてみたいときは評価版をダウンロードできます。

 

| | コメント (0)

忘れないうちにOpenSSLでの暗号化と復号 (その1)

今回は完全に備忘録(笑)

 

OpenSSLで暗号の基本を復習する。

電子署名は、秘密鍵で暗号化して公開鍵で復号する

SSL(TSL)は、公開鍵で暗号化して秘密鍵で復号する

まずはやってみる

このページを参考にした。

OpenSSL で RSA の秘密鍵を作成する方法WEB ARCH LABO

 

秘密鍵をつくる

openssl genrsa」コマンドで、2024bit(253バイト)のRSA秘密鍵を作る。通常は2048bit。ビット数を少なくした時の状態が見たかったので記事のまま指定してみた。コマンドの詳細はリンク先を参照

$ openssl genrsa 2024 > server.key
Generating RSA private key, 2024 bit long modulus (2 primes)
................................................................................
.....................................+++++
.........................+++++
e is 65537 (0x010001)

 

できたキーの中身をテキストとして表示してみる

$ cat server.key
-----BEGIN RSA PRIVATE KEY-----
MIIEjwIBAAKB/gDeRJbhTAshOXp6uJig8IGfZEvofJb5ndHVwm5o4UssOsEWxlPb
VZkO2V3HmfDNbYzSvI5WIFYb3FW+e0cZf+0zh+drECs/8pJ5ryQhJgNqVXn2gR5m
(略)
CfSTk/DqVqK6mFsduBRtdp8+p2Pde/h1aSwfrUiiCvDbZOJvb0JcRLC4CUL8MYOU
iN+SgL5CC9cOFo3/mKncY19psQExepkSnwNv39PbSS7xLicO++tDW3arMtcn7k6t
Dz3rHznsGgUymLsjvcdlwX6Zdw==
-----END RSA PRIVATE KEY-----

頭と最後に種類の表示があって、中身がbase64でエンコードされているのでpem形式の鍵である。ちなみに改行はLF(0x0A)である。

 

詳しく見てみよう「openssl rsa」を使う。「-text」オプションでプレーンテキストの出力となる。「-in」で入力ファイル(秘密鍵)を指定。

$ openssl rsa -text -in server.key
RSA Private-Key: (2024 bit, 2 primes)
modulus:
00:de:44:96:e1:4c:0b:21:39:7a:7a:b8:98:a0:f0:
81:9f:64:4b:e8:7c:96:f9:9d:d1:d5:c2:6e:68:e1:
(略)
publicExponent: 65537 (0x10001)
privateExponent:
00:bd:77:28:4a:4a:a1:1e:24:39:f4:8c:90:86:78:
1d:76:7a:6f:7e:71:5d:dc:d0:1c:03:a4:26:ab:be:
(略)
prime1:
0f:56:0d:7e:f0:16:ca:e7:62:14:98:bc:6e:46:52:
0f:cd:3f:1f:18:d5:ea:ba:f1:c9:cb:2b:20:b8:15:
(略)
prime2:
0e:7e:3a:60:ce:5c:d9:8f:06:82:05:b1:40:b3:e5:
57:f0:1c:eb:81:bf:fa:ce:6a:ca:b0:7a:5d:2a:04:
(略)
exponent1:
0c:48:e1:3c:aa:73:87:8b:3b:5c:c6:50:42:81:5f:
e0:ba:87:72:90:81:62:aa:e7:5d:be:ba:48:56:4c:
(略)
exponent2:
03:15:cd:d9:93:b4:62:3f:b7:13:f0:a0:45:f4:c5:
aa:8d:9b:aa:6a:89:72:9b:84:52:37:75:24:e5:ef:
(略)
coefficient:
03:e0:f6:14:9b:95:01:01:8f:28:aa:fd:09:f4:93:
93:f0:ea:56:a2:ba:98:5b:1d:b8:14:6d:76:9f:3e:
(略)
writing RSA key -----BEGIN RSA PRIVATE KEY-----
MIIEjwIBAAKB/gDeRJbhTAshOXp6uJig8IGfZEvofJb5ndHVwm5o4UssOsEWxlPb
VZkO2V3HmfDNbYzSvI5WIFYb3FW+e0cZf+0zh+drECs/8pJ5ryQhJgNqVXn2gR5m
(略)
iN+SgL5CC9cOFo3/mKncY19psQExepkSnwNv39PbSS7xLicO++tDW3arMtcn7k6t
Dz3rHznsGgUymLsjvcdlwX6Zdw==
-----END RSA PRIVATE KEY-----

modulus部分は公開鍵の部分だ。bit列だが、RSAなので生成時に指定したbit数の正の整数である。ビッグ エンディアンで格納されている。今回は2024bitなので253バイトのはずであるが、先頭bitが1のため負数になってしまうので、先頭に1バイトの0を追加して254バイトになってる。

それぞれの数値の意味は次のサイトが詳しい

RSA鍵の要素と暗号化Qiita

 

公開鍵をつくる

openssl rsa」で公開鍵を作る。作るというより秘密鍵から公開鍵を取り出すと言ったほうが正しい。「-pubout」オプションで公開鍵を取り出す。コマンドがgen~ではなくrsaであることからも、作るのではなくRSA鍵を操作して取り出すという意味合いなのだろう。

$ openssl rsa -in server.key -out pub.key -pubout
writing RSA key

 

できたキーの中身をテキストとして表示してみる

$ cat pub.key
-----BEGIN PUBLIC KEY-----
MIIBHjANBgkqhkiG9w0BAQEFAAOCAQsAMIIBBgKB/gDeRJbhTAshOXp6uJig8IGf
ZEvofJb5ndHVwm5o4UssOsEWxlPbVZkO2V3HmfDNbYzSvI5WIFYb3FW+e0cZf+0z
h+drECs/8pJ5ryQhJgNqVXn2gR5m6UIZikS300f1Rzd4+GyW5SJxJ4cogi45/v+Y
yNrIsC6PGXk6rOHmuAoCHIzF6fPq+dsNuZP9iwMXwH4UgEJa9nI8GKsM3NiX1IdH
5evHhdNzeTWYsWxPzJvBIfckNIT8KGlE5o4s3HsmLQHa2jGjxFkk086JeOcc0QrL
9b3TsgvYzfzvGMQovYaAAg+O7RANdZuo+X2jspmH9OcbAPH6QzuSCXdA63tLAgMB
AAE=
-----END PUBLIC KEY-----

同じくpem形式のファイルになってる

 

秘密鍵の時と同じように詳細を見てよう。「-pubin」で公開鍵を読み込むことを指定する。

$ openssl rsa -text -pubin -in pub.key
RSA Public-Key: (2024 bit)
Modulus:
00:de:44:96:e1:4c:0b:21:39:7a:7a:b8:98:a0:f0:
81:9f:64:4b:e8:7c:96:f9:9d:d1:d5:c2:6e:68:e1:
(略)
e7:1b:00:f1:fa:43:3b:92:09:77:40:eb:7b:4b
Exponent: 65537 (0x10001)
writing RSA key
-----BEGIN PUBLIC KEY-----
MIIBHjANBgkqhkiG9w0BAQEFAAOCAQsAMIIBBgKB/gDeRJbhTAshOXp6uJig8IGf
ZEvofJb5ndHVwm5o4UssOsEWxlPbVZkO2V3HmfDNbYzSvI5WIFYb3FW+e0cZf+0z
(略)
-----END PUBLIC KEY-----

秘密鍵のModulus:部分が公開鍵であることが確認できる。Exponent:は公開指数(public exponent)と呼ばれるもので鍵生成の元となる数字らしいがよくわからない(笑)奇数じゃないといけないらしいが、ほぼ全部この数字。謎だ。

ここに詳しい説明あった。

RSA鍵の要素と暗号化Qiita

 

今日はここまで

 


歯科電子カルテシステム・カルテメーカー は利用料月額16,500円(税込)
MacとWinの両方で利用可能な電子カルテです。介護保険にも対応してます。

カルテメーカーの詳細はカルテメーカー・ホームページまで。
カルテメーカーを実際に動かしてみたいときは評価版をダウンロードできます。

 

| | コメント (0)

2022年8月 9日 (火)

電子処方箋対応 4Dプラグイン開発 pkcs#11、OpenSSL、電子署名、HPKIカード 導入備忘録

電子処方箋の電子署名はHPKIカードでおこないます。このための処理は4Dの標準機能では当然できないのでプラグインで機能を実装しなければいけません。

HPKIカードで電子署名をするためには、pkcs#11ライブラリとOpenSSLライブラリが必要です。この記事はこれらをプラグイン開発プロジェクトの下準備のための備忘録です。

pkcs#11
暗号化トークン・インタフェース標準。暗号化トークンにアクセスしてトークン内部の情報やアプリケーションを利用するための標準的なインターフェースを定めた規格。

暗号化トークン
トークンの意味は「印、象徴」。暗号化トークンといった場合は、暗号化のための電子鍵等を搭載したICカードやUSB装置などの物理的な物を指す。現在の一般的なものはICカード。マイナンバーカードが代表例。今回使うのはHPKIカード

OpenSSL
電子的な暗号を扱うための総合的なオープンソースのライブラリ、暗号、PKI(公開鍵基盤)、SSL/TSLなどなど、ほぼあらゆる暗号化関連処理をすることができるライブラリ。現在のバージョンは3であるが、最新バージョンを使ってる例はまだほとんどない、実質的な標準はバージョン1.1

 

とりあえず読むべきもの

まずはなんといってもここ

保健医療福祉分野公開鍵基盤 電子認証局のご案内MeDis

この中のこのページの資料は特に重要、「はじめてのHPKI ~実装の手引き~」は最重要、ダウンロードして10回以上は読むべし

やさしいHPKIMeDis

サンプルコードも必須。開発にも使うので必ずダウンロード。VisualStudioのプロジェクトファイルなのでダウンロードしてプロジェクトファイルをダブルクリックして開きましょう。必読、ここからいろいろとコピペして開発する。

次に本家本元、「JAHIS 保健医療福祉情報システム工業会」ここに標準規格の規格書等があります。こちらのHPKI関連も必読

JAHIS標準・技術文書JAHIS 保健医療福祉情報システム工業会

とりあえず以下の文書は読んでおく

JAHISヘルスケアPKIを利用した医療文書に対する電子署名規格Ver.2.0
JAHIS HPKI対応ICカードガイドラインVer.3.0
JAHIS電子処方箋実装ガイドVer.1.2
JAHIS院外処方箋2次元シンボル記録条件規約Ver.1.7
JAHIS電子版お薬手帳データフォーマット仕様書Ver.2.4

 

準備するもの

VisualStudio

開発環境、HPKIカードドライバの関係でwindowsしか使えないので、これを使う。Mocrosoft Storeから無料でダウンロードできる。Visual Studio Community 2022というのをダウンロード。インストール時にどれをインストールするかって表示されるけど、よくわからなかったのでとりあえずコマンドライン ツールが作成できてC/C++、C#で開発できそうなのを選んだ。まぁ、適当でもなんとかなった。結果オーライ(笑)

 

4D プラグインSDK

4Dのプラグインを開発するのに必須。特にプロジェクトのスケルトンを作る「4D Plugin Wizard」は便利。GitHubはあまり利用していないし、これ自体の開発を手伝うわけじゃないので、zipでダウンロードして展開して使ってます。使い方はdocsフォルダの中のindex.htmlを開くとドキュメントが読める(英語)

4D-Plugin-SDKGitHub

 

medisのサンプルコード

最初に紹介した「やさしいHPKI」ページにあるサンプルコードをダウンロード。.slnファイルをダブルクリックでVisualStudioが起動する。

やさしいHPKIMeDis

 

テスト用HPKIカード、HPKIカードドライバ

テストカードの貸出しMeDis

このページに書いてあるように問い合わせページに書いてあるメールアドレスへカードを貸してくれとメールを送信。ちなみに無料です。

数日で、申し込み用紙がメールで届くので、印刷して郵送する。なんだか事業所の実在を証明するので、会社のパンフレット等を同封してというので、適当にホームページを印刷して送付。HPKIカードドライバも必要なので、送ってもらうように記述

どの資格でのHPKIカードでも発行してもらえます。

注意!!本人限定受取」郵便という特殊な方法で届く。受け取れるのは送付を依頼した個人の自宅限定。免許証などで本人確認ができる住所以外では受け取れない。事業所宛に配送してもらうと受け取れないので注意。最初にハガキが届くので、配送先や受取方法、日付時間等をハガキかwebで郵便局に伝えると配送される。郵便局に受取にいってもいいが、送付先住所と免許証等(写真付きが必須)の身分証明書の住所が一致してないと受け取れない。

医師会薬剤師会の証明局からも入手可能。どちらも有料。

 

ICカードリーダー

マイナンバーカード対応と書いてあれば、基本なんでもいいのですが、とりあえず購入して動作確認ができてるのは、定番中の定番、NTTコミュニケーションズのACR39-NTTComです。ソニーのPaSoRi RC-S380も定番ですね。これもおすすめ。

それにしても高くなったなぁ、どっちも2021年に購入して2800円くらいだったのに、NTTのは3800円、ソニーは5600円、まぁ、安いのもあるけど、ちょっと使うのは...

windowsであれば、USBを繋ぐだけでドライバのインストールとか自動でおこなって認識されます。

 

ドライバー、ライブラリのインストール

HPKIカードドライバーのインストール

ICカードリーダーを接続するとPC/SC(ICカードを利用するための基本的なAPI)を使うことが可能になるドライバーが自動的にインストールされる。

PC/SCのインターフェースを使ってHPKIカードを操作することも原理的には可能であるが、コマンドを16進の機械語みたいな感じで送るとか、あまりにプリミティブで、かつ、利用するための資料が圧倒的に少ないので現実的にこれでプログラムすることは不可能だろう。

そこで、より上位のPKIミドルウェア層のPKCS#11、CryptoAPIなどのPKIドライバ(ライブラリ)を導入して、PKCS#11、CryptoAPI、Cryptography API: Next Generationインターフェースでプログラムできるようにします。

20220809-132913
JAHIS HPKI 対応 IC カードガイドライン Ver.3.0 より

このドライバ、ライブラリはmedis等からHPKIカードと一緒に送られてくる「HPKIカードドライバセット Version 1.50」という円盤に入っています。

円盤の中のドキュメントに従ってインストールします。途中でICカードリーダーの選択画面がでますので、インストール前にカードリーダーをPCに接続しておくといいでしょう。(後でも選択できる)

PKCS#11用のDLLファイルがC:¥Windows¥System32にインストール、CryptoAPIのサービスドライバ(場所不明)、関連するライブラリ、ドライバ(場所不明)がインストールされる。また、ユーティリティソフトで「PIN変更ツール」「証明書表示ツール」「リーダライタ選択ツール」の3つもインストールされる。名前の通りの機能のアプリなので、適宜利用する。

インストールが正しく行われたかは、HPKIカードをリーダーにセットして「証明書表示ツール」を使うといいだろう。アプリケーションが2つ表示され、その中に証明書が表示されればOK。

26

ダブルクリックすると証明書の詳細が表示されるが、中間CA証明書もルートCA証明書もないので信頼されていないと表示されるはずである。

 

OpenSSLのインストール

暗号と電子署名といえば定番OpenSSL

これが無いと何にもできません。ライブラリもそうですがコマンドラインからも使えるようにしておくのが大事。コマンドラインからいろいろ試すことで電子署名について理解が深まる。ちなみにコマンドラインで操作するならMacがおすすめ。OpenSSLの記事のほとんどはLinuxベースなのでWinのコマンドプロンプトでは直接試せない場合が多い。

インストールは「初めてのHPKI」で紹介している以下のサイトがお勧め。コンパイル済みのバイナリで配布されているのを使うので簡単にインストールできる。

windows10でOpenSSLのインストールとアンインストールの方法ONE NOTES

記事では32bitバージョンを選択してるけど、今なら64bit版の「Win64 OpenSSL v1.1.1q」を選択。v3.xは全く別物なので過去の知識が全然使えないのでパス(間違ってインストールしたけどどうにもならなかったw)

インストール先は記事と違ってデフォルトのC:¥Program Files¥OpenSSL-Win64のまま。記事の場所にインストールするとmedisのサンプルコードのプロジェクトのPathを修正しないとビルドできないと思います。DLLファイルの場所は記事を同じ/binにしました。DLLファイルの場所は、システムフォルダの方が良かった気がするけど、/binでも問題なかった。

Pathの設定は、記事とは微妙に違っていて「設定」→「システム」→「詳細情報」→「システムの詳細情報」で「システムのプロパティ」画面が開きます。

追加するパスはインストールした場所なので、今回はC:¥Program Files¥OpenSSL-Win64

 

おまけ、Macの場合

インストールの時に使ったサイトが消えちゃったので、適当に検索してください。大体みんな同じです。ターミナルを開いて

$ brew install openssl

でダウンロード&インストールされます。あっ事前にhomebrewはインストールしておいてくださいね。正しくインストールされると

$ which openssl
/usr/local/opt/openssl@1.1/bin/openssl
$ openssl version
OpenSSL 1.1.1q  5 Jul 2022

となります。うまくいかない時はこちらのサイトが参考になるかなぁ

macOSでopensslコマンド打つとエラーになるQiita homebrewでinstlalしたOpenSSLが反映されず、OSX標準のOpenSSLが使用されてしまう場合の対処方法

 


とりあえず前準備はこのくらいかな。次は実際にプロジェクトのビルドの時の設定とかを解説します。

 


歯科電子カルテシステム・カルテメーカー は利用料月額16,500円(税込)
MacとWinの両方で利用可能な電子カルテです。介護保険にも対応してます。

カルテメーカーの詳細はカルテメーカー・ホームページまで。
カルテメーカーを実際に動かしてみたいときは評価版をダウンロードできます。

 

| | コメント (0)