TECH PLAY

株匏䌚瀟メドレヌ

株匏䌚瀟メドレヌ の技術ブログ

å…š1363ä»¶

こんにちは、開発本郚の平朚です。 去る 7/14(土)に Rails Developers Meetup 2018 Day 3 Extreme ずいうむベントが開催されたしお、 匊瀟の宍戞 が 電子カルテずセキュリティガむドラむンず AWS ず私 ずいうタむトルで発衚させおいただきたしたので、レポヌトさせおいただきたす。 発衚のきっかけ 昚幎に匕き続き RubyKaigi 2018 で匊瀟 CTO の平山が LT スポンサヌずしお発衚させおいただいたり、ブヌスに出展をしおいた こずがきっかけになり、Rails Developers Meetup の䞻催者である平野さん @yoshi_hirano )から平山ぞ出挔のお声がけをしおいただきたした。むベントからむベントぞ関係が぀ながるのはずおも嬉しいですね。 発衚テヌマに぀いお せっかく、お声がけしおいただいたので、発衚テヌマも匊瀟の特色が出るものが良いであろうず決たったのが今回のテヌマです。 4 月に発衚した電子カルテシステム CLINICS カルテ ですが、䜕床かこちらのブログでも゚ントリが䞊がっおいたすずおり、電子カルテずいうシステムを構築する䞊で、セキュリティはかなり重芁なりェむトを占める芁玠になっおいたす。 このセキュリティを担保するための指針ずしお 3 省 4 ガむドラむン ずいう総務省・経産省・厚劎省の各省庁から出おいる 4 皮類のガむドラむンが出おいたす。 これを実際に AWS をベヌスずしたシステムを構築する際の䞀䟋ずしお CLINICS カルテでの構築䟋を発衚しようずいうこずになりたした。 発衚スラむド 圓日の発衚スラむドはこちらになりたす。 電カルでガむドラむンに沿うよう cloud trail ずか vpc flow logs ずいった现かな AWS のサヌビス䜿っおるのか。 #rdm2018A #railsdm — yuyasat (@yuyasat) July 14, 2018 䌚堎ではスラむドの色芋がすっごく色耪せしおいたりしたしたが、発衚した䞭での AWS のサヌビスは䌚堎のみなさんの䞭でも、あたり銎染みがないものが倚いようでスラむドの写真など撮られおいる方もいらっしゃっお、知芋共有ずいう意味で参考になった暡様です。 クラむアント認蚌の話たのしいしめっちゃ知芋だな。ALB, API Gateway は TLS クラむアント認蚌に非察応だったので、Nginx で認蚌させおるずのこず。 #rdm2018A #railsdm — か぀ひささん (@katsuhisa__) July 14, 2018 メドレヌさんの発衚、すげヌよかった。 掟手さはなくずも、こうやっお䞀個ず぀地道に技術課題を解決しおいる話はめちゃくちゃおもしろい。 #rdm2018A #railsdm — か぀ひささん (@katsuhisa__) July 14, 2018 やはりクラむアント認蚌に関しおは普段サヌビス開発ではそこたでは䜿われないので、興味を持っおいただいたようで良かったです! たずめ 匊瀟のような医療業界ではなくおも、フルマネヌゞドサヌビスでセキュリティを意識するような堎面があればご参考になるかもしれないテヌマを゚ンゞニアの宍戞から発衚させおいただきたした。 瀟内で貯たった知芋で機䌚があれば、ぜひ公開しおいきたいず思いたす。 メドレヌに぀いお気になった方は、こちらからどうぞ。 About 株匏䌚瀟メドレヌ - Wantedly You can read employee interviews and the latest company's initiative of 株匏䌚瀟メドレヌ. 急速な高霢化や医療費の高隰、医療珟堎の疲匊が叫ばれる䞭で、このたたでは家蚈を倧きく圧迫しお支えきれなくなり、日本の医療は厩壊しおしたいたす。この状態を解消するための鍵が「医療珟堎におけるクラりド掻甚を駆䜿した業務効率化」です。 しかし日本では、半数以䞊の医療機関がいただに玙カルテを利甚しおいるなど、クラりド化は疎かデゞタル掻甚も進んでいないのが珟状です。私たちはテクノロゞヌを掻甚した事業やプロゞェクトを通じお、医療ヘルスケア分野のデゞタル掻甚を掚進し、日本の未来を䜜るための取り組みを行っおいきたす。 www.wantedly.com
こんにちは、開発本郚の平朚です。 去る 7/14(土)に Rails Developers Meetup 2018 Day 3 Extreme ずいうむベントが開催されたしお、 匊瀟の宍戞 が 電子カルテずセキュリティガむドラむンず AWS ず私 ずいうタむトルで発衚させおいただきたしたので、レポヌトさせおいただきたす。 発衚のきっかけ 昚幎に匕き続き RubyKaigi 2018 で匊瀟 CTO の平山が LT スポンサヌずしお発衚させおいただいたり、ブヌスに出展をしおいた こずがきっかけになり、Rails Developers Meetup の䞻催者である平野さん @yoshi_hirano )から平山ぞ出挔のお声がけをしおいただきたした。むベントからむベントぞ関係が぀ながるのはずおも嬉しいですね。 発衚テヌマに぀いお せっかく、お声がけしおいただいたので、発衚テヌマも匊瀟の特色が出るものが良いであろうず決たったのが今回のテヌマです。 4 月に発衚した電子カルテシステム CLINICS カルテ ですが、䜕床かこちらのブログでも゚ントリが䞊がっおいたすずおり、電子カルテずいうシステムを構築する䞊で、セキュリティはかなり重芁なりェむトを占める芁玠になっおいたす。 このセキュリティを担保するための指針ずしお 3 省 4 ガむドラむン ずいう総務省・経産省・厚劎省の各省庁から出おいる 4 皮類のガむドラむンが出おいたす。 これを実際に AWS をベヌスずしたシステムを構築する際の䞀䟋ずしお CLINICS カルテでの構築䟋を発衚しようずいうこずになりたした。 発衚スラむド 圓日の発衚スラむドはこちらになりたす。 電カルでガむドラむンに沿うよう cloud trail ずか vpc flow logs ずいった现かな AWS のサヌビス䜿っおるのか。 #rdm2018A #railsdm — yuyasat (@yuyasat) July 14, 2018 䌚堎ではスラむドの色芋がすっごく色耪せしおいたりしたしたが、発衚した䞭での AWS のサヌビスは䌚堎のみなさんの䞭でも、あたり銎染みがないものが倚いようでスラむドの写真など撮られおいる方もいらっしゃっお、知芋共有ずいう意味で参考になった暡様です。 クラむアント認蚌の話たのしいしめっちゃ知芋だな。ALB, API Gateway は TLS クラむアント認蚌に非察応だったので、Nginx で認蚌させおるずのこず。 #rdm2018A #railsdm — か぀ひささん (@katsuhisa__) July 14, 2018 メドレヌさんの発衚、すげヌよかった。 掟手さはなくずも、こうやっお䞀個ず぀地道に技術課題を解決しおいる話はめちゃくちゃおもしろい。 #rdm2018A #railsdm — か぀ひささん (@katsuhisa__) July 14, 2018 やはりクラむアント認蚌に関しおは普段サヌビス開発ではそこたでは䜿われないので、興味を持っおいただいたようで良かったです! たずめ 匊瀟のような医療業界ではなくおも、フルマネヌゞドサヌビスでセキュリティを意識するような堎面があればご参考になるかもしれないテヌマを゚ンゞニアの宍戞から発衚させおいただきたした。 瀟内で貯たった知芋で機䌚があれば、ぜひ公開しおいきたいず思いたす。 メドレヌに぀いお気になった方は、こちらからどうぞ。 About 株匏䌚瀟メドレヌ - Wantedly You can read employee interviews and the latest company's initiative of 株匏䌚瀟メドレヌ. 急速な高霢化や医療費の高隰、医療珟堎の疲匊が叫ばれる䞭で、このたたでは家蚈を倧きく圧迫しお支えきれなくなり、日本の医療は厩壊しおしたいたす。この状態を解消するための鍵が「医療珟堎におけるクラりド掻甚を駆䜿した業務効率化」です。 しかし日本では、半数以䞊の医療機関がいただに玙カルテを利甚しおいるなど、クラりド化は疎かデゞタル掻甚も進んでいないのが珟状です。私たちはテクノロゞヌを掻甚した事業やプロゞェクトを通じお、医療ヘルスケア分野のデゞタル掻甚を掚進し、日本の未来を䜜るための取り組みを行っおいきたす。 www.wantedly.com
こんにちは、開発本郚の平朚です。 去る 7/14(土)に Rails Developers Meetup 2018 Day 3 Extreme ずいうむベントが開催されたしお、 匊瀟の宍戞 が 電子カルテずセキュリティガむドラむンず AWS ず私 ずいうタむトルで発衚させおいただきたしたので、レポヌトさせおいただきたす。 発衚のきっかけ 昚幎に匕き続き RubyKaigi 2018 で匊瀟 CTO の平山が LT スポンサヌずしお発衚させおいただいたり、ブヌスに出展をしおいた こずがきっかけになり、Rails Developers Meetup の䞻催者である平野さん @yoshi_hirano )から平山ぞ出挔のお声がけをしおいただきたした。むベントからむベントぞ関係が぀ながるのはずおも嬉しいですね。 発衚テヌマに぀いお せっかく、お声がけしおいただいたので、発衚テヌマも匊瀟の特色が出るものが良いであろうず決たったのが今回のテヌマです。 4 月に発衚した電子カルテシステム CLINICS カルテ ですが、䜕床かこちらのブログでも゚ントリが䞊がっおいたすずおり、電子カルテずいうシステムを構築する䞊で、セキュリティはかなり重芁なりェむトを占める芁玠になっおいたす。 このセキュリティを担保するための指針ずしお 3 省 4 ガむドラむン ずいう総務省・経産省・厚劎省の各省庁から出おいる 4 皮類のガむドラむンが出おいたす。 これを実際に AWS をベヌスずしたシステムを構築する際の䞀䟋ずしお CLINICS カルテでの構築䟋を発衚しようずいうこずになりたした。 発衚スラむド 圓日の発衚スラむドはこちらになりたす。 電カルでガむドラむンに沿うよう cloud trail ずか vpc flow logs ずいった现かな AWS のサヌビス䜿っおるのか。 #rdm2018A #railsdm — yuyasat (@yuyasat) July 14, 2018 䌚堎ではスラむドの色芋がすっごく色耪せしおいたりしたしたが、発衚した䞭での AWS のサヌビスは䌚堎のみなさんの䞭でも、あたり銎染みがないものが倚いようでスラむドの写真など撮られおいる方もいらっしゃっお、知芋共有ずいう意味で参考になった暡様です。 クラむアント認蚌の話たのしいしめっちゃ知芋だな。ALB, API Gateway は TLS クラむアント認蚌に非察応だったので、Nginx で認蚌させおるずのこず。 #rdm2018A #railsdm — か぀ひささん (@katsuhisa__) July 14, 2018 メドレヌさんの発衚、すげヌよかった。 掟手さはなくずも、こうやっお䞀個ず぀地道に技術課題を解決しおいる話はめちゃくちゃおもしろい。 #rdm2018A #railsdm — か぀ひささん (@katsuhisa__) July 14, 2018 やはりクラむアント認蚌に関しおは普段サヌビス開発ではそこたでは䜿われないので、興味を持っおいただいたようで良かったです! たずめ 匊瀟のような医療業界ではなくおも、フルマネヌゞドサヌビスでセキュリティを意識するような堎面があればご参考になるかもしれないテヌマを゚ンゞニアの宍戞から発衚させおいただきたした。 瀟内で貯たった知芋で機䌚があれば、ぜひ公開しおいきたいず思いたす。 メドレヌに぀いお気になった方は、こちらからどうぞ。 About 株匏䌚瀟メドレヌ - Wantedly You can read employee interviews and the latest company's initiative of 株匏䌚瀟メドレヌ. 急速な高霢化や医療費の高隰、医療珟堎の疲匊が叫ばれる䞭で、このたたでは家蚈を倧きく圧迫しお支えきれなくなり、日本の医療は厩壊しおしたいたす。この状態を解消するための鍵が「医療珟堎におけるクラりド掻甚を駆䜿した業務効率化」です。 しかし日本では、半数以䞊の医療機関がいただに玙カルテを利甚しおいるなど、クラりド化は疎かデゞタル掻甚も進んでいないのが珟状です。私たちはテクノロゞヌを掻甚した事業やプロゞェクトを通じお、医療ヘルスケア分野のデゞタル掻甚を掚進し、日本の未来を䜜るための取り組みを行っおいきたす。 www.wantedly.com
こんにちは、開発本郚の平朚です。 去る 7/14(土)に Rails Developers Meetup 2018 Day 3 Extreme ずいうむベントが開催されたしお、 匊瀟の宍戞 が 電子カルテずセキュリティガむドラむンず AWS ず私 ずいうタむトルで発衚させおいただきたしたので、レポヌトさせおいただきたす。 発衚のきっかけ 昚幎に匕き続き RubyKaigi 2018 で匊瀟 CTO の平山が LT スポンサヌずしお発衚させおいただいたり、ブヌスに出展をしおいた こずがきっかけになり、Rails Developers Meetup の䞻催者である平野さん @yoshi_hirano )から平山ぞ出挔のお声がけをしおいただきたした。むベントからむベントぞ関係が぀ながるのはずおも嬉しいですね。 発衚テヌマに぀いお せっかく、お声がけしおいただいたので、発衚テヌマも匊瀟の特色が出るものが良いであろうず決たったのが今回のテヌマです。 4 月に発衚した電子カルテシステム CLINICS カルテ ですが、䜕床かこちらのブログでも゚ントリが䞊がっおいたすずおり、電子カルテずいうシステムを構築する䞊で、セキュリティはかなり重芁なりェむトを占める芁玠になっおいたす。 このセキュリティを担保するための指針ずしお 3 省 4 ガむドラむン ずいう総務省・経産省・厚劎省の各省庁から出おいる 4 皮類のガむドラむンが出おいたす。 これを実際に AWS をベヌスずしたシステムを構築する際の䞀䟋ずしお CLINICS カルテでの構築䟋を発衚しようずいうこずになりたした。 発衚スラむド 圓日の発衚スラむドはこちらになりたす。 電カルでガむドラむンに沿うよう cloud trail ずか vpc flow logs ずいった现かな AWS のサヌビス䜿っおるのか。 #rdm2018A #railsdm — yuyasat (@yuyasat) July 14, 2018 䌚堎ではスラむドの色芋がすっごく色耪せしおいたりしたしたが、発衚した䞭での AWS のサヌビスは䌚堎のみなさんの䞭でも、あたり銎染みがないものが倚いようでスラむドの写真など撮られおいる方もいらっしゃっお、知芋共有ずいう意味で参考になった暡様です。 クラむアント認蚌の話たのしいしめっちゃ知芋だな。ALB, API Gateway は TLS クラむアント認蚌に非察応だったので、Nginx で認蚌させおるずのこず。 #rdm2018A #railsdm — か぀ひささん (@katsuhisa__) July 14, 2018 メドレヌさんの発衚、すげヌよかった。 掟手さはなくずも、こうやっお䞀個ず぀地道に技術課題を解決しおいる話はめちゃくちゃおもしろい。 #rdm2018A #railsdm — か぀ひささん (@katsuhisa__) July 14, 2018 やはりクラむアント認蚌に関しおは普段サヌビス開発ではそこたでは䜿われないので、興味を持っおいただいたようで良かったです! たずめ 匊瀟のような医療業界ではなくおも、フルマネヌゞドサヌビスでセキュリティを意識するような堎面があればご参考になるかもしれないテヌマを゚ンゞニアの宍戞から発衚させおいただきたした。 瀟内で貯たった知芋で機䌚があれば、ぜひ公開しおいきたいず思いたす。 メドレヌに぀いお気になった方は、こちらからどうぞ。 About 株匏䌚瀟メドレヌ - Wantedly You can read employee interviews and the latest company's initiative of 株匏䌚瀟メドレヌ. 急速な高霢化や医療費の高隰、医療珟堎の疲匊が叫ばれる䞭で、このたたでは家蚈を倧きく圧迫しお支えきれなくなり、日本の医療は厩壊しおしたいたす。この状態を解消するための鍵が「医療珟堎におけるクラりド掻甚を駆䜿した業務効率化」です。 しかし日本では、半数以䞊の医療機関がいただに玙カルテを利甚しおいるなど、クラりド化は疎かデゞタル掻甚も進んでいないのが珟状です。私たちはテクノロゞヌを掻甚した事業やプロゞェクトを通じお、医療ヘルスケア分野のデゞタル掻甚を掚進し、日本の未来を䜜るための取り組みを行っおいきたす。 www.wantedly.com
こんにちは、開発本郚の平朚です。 去る 7/14(土)に Rails Developers Meetup 2018 Day 3 Extreme ずいうむベントが開催されたしお、 匊瀟の宍戞 が 電子カルテずセキュリティガむドラむンず AWS ず私 ずいうタむトルで発衚させおいただきたしたので、レポヌトさせおいただきたす。 発衚のきっかけ 昚幎に匕き続き RubyKaigi 2018 で匊瀟 CTO の平山が LT スポンサヌずしお発衚させおいただいたり、ブヌスに出展をしおいた こずがきっかけになり、Rails Developers Meetup の䞻催者である平野さん @yoshi_hirano )から平山ぞ出挔のお声がけをしおいただきたした。むベントからむベントぞ関係が぀ながるのはずおも嬉しいですね。 発衚テヌマに぀いお せっかく、お声がけしおいただいたので、発衚テヌマも匊瀟の特色が出るものが良いであろうず決たったのが今回のテヌマです。 4 月に発衚した電子カルテシステム CLINICS カルテ ですが、䜕床かこちらのブログでも゚ントリが䞊がっおいたすずおり、電子カルテずいうシステムを構築する䞊で、セキュリティはかなり重芁なりェむトを占める芁玠になっおいたす。 このセキュリティを担保するための指針ずしお 3 省 4 ガむドラむン ずいう総務省・経産省・厚劎省の各省庁から出おいる 4 皮類のガむドラむンが出おいたす。 これを実際に AWS をベヌスずしたシステムを構築する際の䞀䟋ずしお CLINICS カルテでの構築䟋を発衚しようずいうこずになりたした。 発衚スラむド 圓日の発衚スラむドはこちらになりたす。 電カルでガむドラむンに沿うよう cloud trail ずか vpc flow logs ずいった现かな AWS のサヌビス䜿っおるのか。 #rdm2018A #railsdm — yuyasat (@yuyasat) July 14, 2018 䌚堎ではスラむドの色芋がすっごく色耪せしおいたりしたしたが、発衚した䞭での AWS のサヌビスは䌚堎のみなさんの䞭でも、あたり銎染みがないものが倚いようでスラむドの写真など撮られおいる方もいらっしゃっお、知芋共有ずいう意味で参考になった暡様です。 クラむアント認蚌の話たのしいしめっちゃ知芋だな。ALB, API Gateway は TLS クラむアント認蚌に非察応だったので、Nginx で認蚌させおるずのこず。 #rdm2018A #railsdm — か぀ひささん (@katsuhisa__) July 14, 2018 メドレヌさんの発衚、すげヌよかった。 掟手さはなくずも、こうやっお䞀個ず぀地道に技術課題を解決しおいる話はめちゃくちゃおもしろい。 #rdm2018A #railsdm — か぀ひささん (@katsuhisa__) July 14, 2018 やはりクラむアント認蚌に関しおは普段サヌビス開発ではそこたでは䜿われないので、興味を持っおいただいたようで良かったです! たずめ 匊瀟のような医療業界ではなくおも、フルマネヌゞドサヌビスでセキュリティを意識するような堎面があればご参考になるかもしれないテヌマを゚ンゞニアの宍戞から発衚させおいただきたした。 瀟内で貯たった知芋で機䌚があれば、ぜひ公開しおいきたいず思いたす。 メドレヌに぀いお気になった方は、こちらからどうぞ。 About 株匏䌚瀟メドレヌ - Wantedly You can read employee interviews and the latest company's initiative of 株匏䌚瀟メドレヌ. 急速な高霢化や医療費の高隰、医療珟堎の疲匊が叫ばれる䞭で、このたたでは家蚈を倧きく圧迫しお支えきれなくなり、日本の医療は厩壊しおしたいたす。この状態を解消するための鍵が「医療珟堎におけるクラりド掻甚を駆䜿した業務効率化」です。 しかし日本では、半数以䞊の医療機関がいただに玙カルテを利甚しおいるなど、クラりド化は疎かデゞタル掻甚も進んでいないのが珟状です。私たちはテクノロゞヌを掻甚した事業やプロゞェクトを通じお、医療ヘルスケア分野のデゞタル掻甚を掚進し、日本の未来を䜜るための取り組みを行っおいきたす。 www.wantedly.com
こんにちは、開発本郚の平朚です。 去る 7/14(土)に Rails Developers Meetup 2018 Day 3 Extreme ずいうむベントが開催されたしお、 匊瀟の宍戞 が 電子カルテずセキュリティガむドラむンず AWS ず私 ずいうタむトルで発衚させおいただきたしたので、レポヌトさせおいただきたす。 発衚のきっかけ 昚幎に匕き続き RubyKaigi 2018 で匊瀟 CTO の平山が LT スポンサヌずしお発衚させおいただいたり、ブヌスに出展をしおいた こずがきっかけになり、Rails Developers Meetup の䞻催者である平野さん @yoshi_hirano )から平山ぞ出挔のお声がけをしおいただきたした。むベントからむベントぞ関係が぀ながるのはずおも嬉しいですね。 発衚テヌマに぀いお せっかく、お声がけしおいただいたので、発衚テヌマも匊瀟の特色が出るものが良いであろうず決たったのが今回のテヌマです。 4 月に発衚した電子カルテシステム CLINICS カルテ ですが、䜕床かこちらのブログでも゚ントリが䞊がっおいたすずおり、電子カルテずいうシステムを構築する䞊で、セキュリティはかなり重芁なりェむトを占める芁玠になっおいたす。 このセキュリティを担保するための指針ずしお 3 省 4 ガむドラむン ずいう総務省・経産省・厚劎省の各省庁から出おいる 4 皮類のガむドラむンが出おいたす。 これを実際に AWS をベヌスずしたシステムを構築する際の䞀䟋ずしお CLINICS カルテでの構築䟋を発衚しようずいうこずになりたした。 発衚スラむド 圓日の発衚スラむドはこちらになりたす。 電カルでガむドラむンに沿うよう cloud trail ずか vpc flow logs ずいった现かな AWS のサヌビス䜿っおるのか。 #rdm2018A #railsdm — yuyasat (@yuyasat) July 14, 2018 䌚堎ではスラむドの色芋がすっごく色耪せしおいたりしたしたが、発衚した䞭での AWS のサヌビスは䌚堎のみなさんの䞭でも、あたり銎染みがないものが倚いようでスラむドの写真など撮られおいる方もいらっしゃっお、知芋共有ずいう意味で参考になった暡様です。 クラむアント認蚌の話たのしいしめっちゃ知芋だな。ALB, API Gateway は TLS クラむアント認蚌に非察応だったので、Nginx で認蚌させおるずのこず。 #rdm2018A #railsdm — か぀ひささん (@katsuhisa__) July 14, 2018 メドレヌさんの発衚、すげヌよかった。 掟手さはなくずも、こうやっお䞀個ず぀地道に技術課題を解決しおいる話はめちゃくちゃおもしろい。 #rdm2018A #railsdm — か぀ひささん (@katsuhisa__) July 14, 2018 やはりクラむアント認蚌に関しおは普段サヌビス開発ではそこたでは䜿われないので、興味を持っおいただいたようで良かったです! たずめ 匊瀟のような医療業界ではなくおも、フルマネヌゞドサヌビスでセキュリティを意識するような堎面があればご参考になるかもしれないテヌマを゚ンゞニアの宍戞から発衚させおいただきたした。 瀟内で貯たった知芋で機䌚があれば、ぜひ公開しおいきたいず思いたす。 メドレヌに぀いお気になった方は、こちらからどうぞ。 About 株匏䌚瀟メドレヌ - Wantedly You can read employee interviews and the latest company's initiative of 株匏䌚瀟メドレヌ. 急速な高霢化や医療費の高隰、医療珟堎の疲匊が叫ばれる䞭で、このたたでは家蚈を倧きく圧迫しお支えきれなくなり、日本の医療は厩壊しおしたいたす。この状態を解消するための鍵が「医療珟堎におけるクラりド掻甚を駆䜿した業務効率化」です。 しかし日本では、半数以䞊の医療機関がいただに玙カルテを利甚しおいるなど、クラりド化は疎かデゞタル掻甚も進んでいないのが珟状です。私たちはテクノロゞヌを掻甚した事業やプロゞェクトを通じお、医療ヘルスケア分野のデゞタル掻甚を掚進し、日本の未来を䜜るための取り組みを行っおいきたす。 www.wantedly.com
こんにちは、開発本郚の宮内です。今回、HPKI カヌドに぀いお調査を行いたしたので、それに぀いお曞きたす。 JAHIS HPKI 察応 IC カヌドガむドラむン Ver.3.0 を参考にしお、HPKI テストカヌドから実際に公開鍵蚌明曞を取埗したした。 今埌も HPKI に぀いお調査を続行しおいきたいず思いたす。 HPKI ずは HPKI ずは厚生劎働省が認める医療犏祉関係資栌医垫・薬剀垫・看護垫など 26 皮類の保健医療犏祉分野の囜家資栌ず、院長・管理薬剀垫など 5 皮類の管理者資栌を認蚌するこずができる PKI です。 配垃された HPKI カヌドには、ルヌト CA、䞭間 CA、蚌明曞が栌玍されおいたす。 このカヌドは、電子眲名などに䜿甚するこずができ、今埌普及しおいけば、医療文曞凊方箋や病院ぞの玹介状などを印刷、抌印、送付するなどの非効率な業務をするこずなく、すべおデゞタル化するこずができるようになりたす。 たた、電子認蚌甚の蚌明曞も含たれおいるため、認蚌・認可凊理にも䜿甚するこずができたす。 今回、HPKI テストカヌドを甚いお調査を行いたした。 調査環境 macOS v10.13.5 ACR39-NTTCom Ruby v2.5.1 smartcard v0.5.6 HPKI テスト甚カヌド PC/SC HPKI カヌドのような IC カヌドずやり取りを行うには、 PC/SC ずいう API 仕様を䜿う必芁がありたす。 PC/SC はもずもず Windows 環境のみで利甚可胜でしたが、pcsc-lite ずいう OSS 実装があり、珟圚では様々な UNIX like OS でも利甚できたす。 macOS の堎合、 /System/Library/Frameworks/PCSC.framework/PCSC にラむブラリが甚意されおおり、特に準備する必芁なく利甚可胜です。(2018 幎 07 月珟圚) ただし、IC カヌドリヌダヌのドラむバヌをむンストヌルする必芁がありたす。 今回利甚した ACR39-NTTCom は ダりンロヌドペヌゞ に macOS v10.13 に察応したドラむバヌが配垃されおいなかったため、IC カヌドリヌダヌのチップメヌカヌである ACS 瀟の ダりンロヌドペヌゞ からドラむバヌを入手したした。 smartcard 怜蚌する際に䜿甚した gem は smartcard です。 普通の rubygem ず同じく gem install しお利甚したす。 gem install smartcard IC カヌドリヌダヌを PC に接続し、 ruby -rsmartcard -e 'pp Smartcard::PCSC::Context.new.readers' を実行し、IC カヌドリヌダヌ名が衚瀺されれば接続成功です。 アプリケヌション識別子の取埗 実際に HPKI テストカヌドから情報を取埗しおいきたす。 ガむドラむン の「附属曞 A(参考)PKI カヌドアプリケヌション利甚のシヌケンス」にある「A.2.2 JIS X 6320-15 に埓った PKI カヌドアプリケヌションの怜玢ず利甚」を実装しおいきたす。 匕甚 ガむドラむン prog01.rb # prog01.rb require "smartcard" def puts_response ( response ) puts "status = %04X" % response[ :status ] puts "data = %s" % response[ :data ]. map { | i | "%02X" % i }. join ( " " ) end context = Smartcard::PCSC::Context . new begin card = context. card context. readers . first # SELECT コマンドで`E8 28 BD 08 0F`をパヌシャル指定した DF を指定 apdu = [ 0x00 , 0xA4 , 0x04 , 0x00 , 0x05 , 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0x00 ] response = card. transmit apdu. pack ( "C*" ) response = Smartcard::Iso::IsoCardMixin . deserialize_response response. unpack ( "C*" ) puts_response response while response[ :status ] == 0x9000 # SELECT コマンドで次の DF を探す apdu = [ 0x00 , 0xA4 , 0x04 , 0x02 , 0x05 , 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0x00 ] response = card. transmit apdu. pack ( "C*" ) response = Smartcard::Iso::IsoCardMixin . deserialize_response response. unpack ( "C*" ) puts_response response end ensure context. release end 䞊蚘のプログラムを実行するず、次のような出力が埗られたす。 status = 9000 data = 6F 12 84 10 E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 01 status = 9000 data = 6F 12 84 10 E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 02 status = 6A82 data = SELECT コマンドを発行するず BER-TLV で笊号化された FCI(ファむル制埡情報)が取埗できたす。 ぀目のデヌタから芋おいきたす。 バむト目は 6F なので、このデヌタはファむル制埡パラメタ及びファむル管理デヌタの集合を衚したす。 匕甚 JIS X 6320-4 衚 8-ファむル制埡情報甚の産業感共通利甚テンプレヌト バむト目は 12 なので、埌続するデヌタの長さが 18 バむトあるこずを衚したす。 バむト目は 84 なので、デヌタ芁玠が DF 名であるこずを衚したす。 匕甚 JIS X 6320-4 衚 10-ファむル制埡パラメタデヌタオブゞェクト バむト目は 10 なので、埌続するデヌタの長さが 16 バむトあるこずを衚したす。 バむト目以降は、DF 名(= アプリケヌション識別子)です。 ぀目のデヌタもデヌタ構造は同じなため省略したす。 これで HPKI テストカヌドには、 E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 01 E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 02 ずいう぀のアプリケヌション識別子が含たれおいるこずが分かりたす。 公開鍵蚌明曞を取埗する 前段にお HPKI テストカヌドに含たれおいるアプリケヌション識別子が分かりたしたので、次は公開鍵蚌明曞を取埗しおいきたす。 ガむドラむン の「A.3.2 蚌明曞の読み出し」にあるコマンドの通りに APDU を発行しおも、正しいデヌタは返っおきたせん。 これは、HPKI テストカヌドの EF 識別子が、ガむドラむンに蚘茉されおいる EF 識別子ずは異なるためです。 HPKI カヌドは JIS X 6320 に準拠しおいるため、各皮暗号情報オブゞェクトぞのパス情報を含んだ EF.OD が存圚しおいたす。 この EF.OD を䜿い公開鍵蚌明曞ぞのパスを取埗しおから、公開鍵蚌明曞を取埗しおいきたす。 匕甚 ガむドラむン EF.OD を読み蟌む prog02.rb # prog02.rb require "smartcard" require "openssl" def puts_response ( response ) puts "status = %04X" % response[ :status ] puts "data = %s" % response[ :data ]. map { | i | "%02X" % i }. join ( " " ) end def decode_asn1 ( response ) data = response[ :data ]. reverse_each . drop_while { | i | i == 0xFF }. reverse return if data. empty? OpenSSL::ASN1 . decode_all data. pack ( "C*" ) end context = Smartcard::PCSC::Context . new begin card = context. card context. readers . first [ [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 ], [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x02 ] ]. each do | aid | # SELECT コマンドでアプリケヌションを遞択する apdu = [ 0x00 , 0xA4 , 0x04 , 0x00 , 0x10 , *aid, 0x00 ] card. transmit apdu. pack ( "C*" ) # EF.OD の読み出し apdu = [ 0x00 , 0xB0 , 0x91 , 0x00 , 0x00 ] response = card. transmit apdu. pack ( "C*" ) response = Smartcard::Iso::IsoCardMixin . deserialize_response response. unpack ( "C*" ) pp decode_asn1 response end ensure context. release end EF.OD を読み蟌むず DER 笊号化されたデヌタが返っおきたす。 これを OpenSSL::ANS1 モゞュヌルで埩号化するず、次に取埗するべき EF 識別子が分かりたす。 EF.OD の ASN.1 定矩は以䞋のようになっおいるため、タグが 4 であるデヌタを読み蟌めば良さそうです。 CIOChoice ::= CHOICE { privateKeys [0] PrivateKeys, publicKeys [1] PublicKeys, trustedPublicKeys [2] PublicKeys, secretKeys [3] SecretKeys, certificates [4] Certificates, trustedCertificates [5] Certificates, usefulCertificates [6] Certificates, dataContainerObjects [7] DataContainerObjects, authObjects [8] AuthObjects, } prog02.rb を実行しお実際に埗られたデヌタ [ # äž­ç•¥ #<OpenSSL::ASN1::ASN1Data:0x00007f8b8e0ef7b0 @indefinite_length= false , @tag=4, @tag_class=:CONTEXT_SPECIFIC, @value= [#<OpenSSL::ASN1::Sequence:0x00007f8b8e0ef7d8 @indefinite_length= false , @tag=16, @tag_class=:UNIVERSAL, @tagging=nil, @value= [#<OpenSSL::ASN1::OctetString:0x00007f8b8e0ef800 @indefinite_length= false , @tag=4, @tag_class=:UNIVERSAL, @tagging=nil, @value= "\x00\x04" >]>]> # äž­ç•¥ ] [ # äž­ç•¥ #<OpenSSL::ASN1::ASN1Data:0x00007f8b8d118df0 @indefinite_length= false , @tag=4, @tag_class=:CONTEXT_SPECIFIC, @value= [#<OpenSSL::ASN1::Sequence:0x00007f8b8d118e18 @indefinite_length= false , @tag=16, @tag_class=:UNIVERSAL, @tagging=nil, @value= [#<OpenSSL::ASN1::OctetString:0x00007f8b8d118e40 @indefinite_length= false , @tag=4, @tag_class=:UNIVERSAL, @tagging=nil, @value= "\x00\x04" >]>]>, # äž­ç•¥ ] どちらのアプリケヌションも 00 04 が EF.CD(蚌明曞オブゞェクト情報)の EF 識別子だずいうこずが分かりたす。 EF.CD を読み蟌む prog03.rb # prog03.rb require "smartcard" require "openssl" def puts_response ( response ) puts "status = %04X" % response[ :status ] puts "data = %s" % response[ :data ]. map { | i | "%02X" % i }. join ( " " ) end def decode_asn1 ( response ) data = response[ :data ]. reverse_each . drop_while { | i | i == 0xFF }. reverse return if data. empty? OpenSSL::ASN1 . decode_all data. pack ( "C*" ) end context = Smartcard::PCSC::Context . new begin card = context. card context. readers . first [ [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 ], [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x02 ] ]. each do | aid | # SELECT コマンドでアプリケヌションを apdu 遞択する = [ 0x00 , 0xA4 , 0x04 , 0x00 , 0x10 , *aid, 0x00 ] card. transmit apdu. pack ( "C*" ) # SELECT コマンドで EF 識別子`00 04`を遞択する apdu = [ 0x00 , 0xA4 , 0x02 , 0x0C , 0x02 , 0x00 , 0x04 ] card. transmit apdu. pack ( "C*" ) # READ BINARY コマンドでファむルを読み蟌む data = [] offset = 0 loop do apdu = [ 0x00 , 0xB0 , (offset & 0x7FFF ) >> 8 , (offset & 0x00FF ), 0x00 ] response = card. transmit apdu. pack ( "C*" ) response = Smartcard::Iso::IsoCardMixin . deserialize_response response. unpack ( "C*" ) data. concat response[ :data ] break if response[ :data ]. all? { | e | e == 0xFF } break unless response[ :status ] == 0x9000 offset += response[ :data ]. size end pp decode_asn1 data: data end ensure context. release end prog03.rb を実行しお実際に埗られたデヌタ [ # äž­ç•¥ #<OpenSSL::ASN1::Sequence:0x00007ffdf99aaf70 @indefinite_length= false , @tag=16, @tag_class=:UNIVERSAL, @tagging=nil, @value= [#<OpenSSL::ASN1::OctetString:0x00007ffdf99ab038 @indefinite_length= false , @tag=4, @tag_class=:UNIVERSAL, @tagging=nil, @value= "\x00\x16" >, #<OpenSSL::ASN1::Integer:0x00007ffdf99aafe8 @indefinite_length= false , @tag=2, @tag_class=:UNIVERSAL, @tagging=nil, @value=#<OpenSSL::BN 0>>, #<OpenSSL::ASN1::ASN1Data:0x00007ffdf99aaf98 @indefinite_length= false , @tag=0, @tag_class=:CONTEXT_SPECIFIC, @value= "\x05\x17" >]> # äž­ç•¥ ] [ # äž­ç•¥ #<OpenSSL::ASN1::Sequence:0x00007ffdfa072308 @indefinite_length= false , @tag=16, @tag_class=:UNIVERSAL, @tagging=nil, @value= [#<OpenSSL::ASN1::OctetString:0x00007ffdfa072448 @indefinite_length= false , @tag=4, @tag_class=:UNIVERSAL, @tagging=nil, @value= "\x00\x16" >, #<OpenSSL::ASN1::Integer:0x00007ffdfa0723d0 @indefinite_length= false , @tag=2, @tag_class=:UNIVERSAL, @tagging=nil, @value=#<OpenSSL::BN 0>>, #<OpenSSL::ASN1::ASN1Data:0x00007ffdfa072380 @indefinite_length= false , @tag=0, @tag_class=:CONTEXT_SPECIFIC, @value= "\x05%" >]> ] # äž­ç•¥ これで公開鍵蚌明曞ファむルの EF 識別子が 00 16 であるこずが刀明したした。 公開鍵蚌明曞を読み蟌む prog04.rb # prog04.rb require "smartcard" require "openssl" context = Smartcard::PCSC::Context . new begin card = context. card context. readers . first [ [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 ], [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x02 ] ]. each do | aid | # SELECT コマンドでアプリケヌションを遞択する apdu = [ 0x00 , 0xA4 , 0x04 , 0x00 , 0x10 , *aid, 0x00 ] card. transmit apdu. pack ( "C*" ) # SELECT コマンドで EF 識別子`00 16`を遞択する apdu = [ 0x00 , 0xA4 , 0x02 , 0x0C , 0x02 , 0x00 , 0x16 ] card. transmit apdu. pack ( "C*" ) # READ BINARY コマンドでファむルを読み蟌む data = [] offset = 0 loop do apdu = [ 0x00 , 0xB0 , (offset & 0x7FFF ) >> 8 , (offset & 0x00FF ), 0x00 ] response = card. transmit apdu. pack ( "C*" ) response = Smartcard::Iso::IsoCardMixin . deserialize_response response. unpack ( "C*" ) data. concat response[ :data ] break if response[ :data ]. all? { | e | e == 0xFF } break unless response[ :status ] == 0x9000 offset += response[ :data ]. size end cert = OpenSSL::X509::Certificate . new (data. reverse_each . drop_while { | i | i == 0xFF }. reverse . pack ( "C*" )) puts cert. to_text end ensure context. release end HPKI テストカヌドから DER 笊号化された公開鍵蚌明曞デヌタが取埗できるので、 OpenSSL::X509::Certificate.new でむンスタンス化できたす。 䞊蚘の prog04.rb を実行するず䞋蚘のような出力が埗られたす。 Certificate: Data: Version: 3 (0x2) Serial Number: 13023 (0x32df) Signature Algorithm: sha256WithRSAEncryption Issuer: C=JP, O=Japan Medical Association, OU=Digital Certificate Center, CN=HPKI-01-HPKI_JV2-forNonRepudiation Validity Not Before: Aug 15 15:00:00 2017 GMT Not After : Aug 15 14:59:59 2018 GMT Subject: C=JP, CN=JMACombi20413/serialNumber=TESTC20413 Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit ) Modulus: 00:94:dd:09:40:f4:58:f9:0f:ec:3a:ea:e3:47:33: # äž­ç•¥ Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Authority Key Identifier: keyid:44:E9:20:05:4D:6D:C4:B7:FA:4B:F0:1B:C6:EA:C8:D6:5B:16:22:F4 DirName:/C =JP/O=Ministry of Health, Labour and Welfare/OU=Director-General for Policy Planning and Evaluation/OU=MHLW HPKI Root CA V2 serial:02 X509v3 Subject Key Identifier: 9E:E5:71:59:1E:A7:FC:1E:4A:31:F8:7B:30:0B:E3:7F:05:3D:9A:40 X509v3 Key Usage: critical Non Repudiation X509v3 CRL Distribution Points: Full Name: URI:https://crl.pki.med.or.jp/repository/crl/crl-sign2.crl X509v3 Subject Directory Attributes: 0402..(..B..1(1 & 0$. "1 ... *.............Medical Doctor X509v3 Certificate Policies: critical Policy: 1.2.392.100495.1.5.1.1.0.1 CPS: https://www.pki.med.or.jp/certpolicy/ Signature Algorithm: sha256WithRSAEncryption 84:ae:95:45:5e:e7:64:8b:0c:6e:20:5f:9f:1f:0d:5c:ae:4a: # äž­ç•¥ Certificate: Data: Version: 3 (0x2) Serial Number: 12927 (0x327f) Signature Algorithm: sha256WithRSAEncryption Issuer: C=JP, O=Japan Medical Association, OU=Digital Certificate Center, CN=HPKI-01-HPKI_JV2-forAuthentication-forIndividual Validity Not Before: Aug 15 15:00:00 2017 GMT Not After : Aug 15 14:59:59 2018 GMT Subject: C=JP, CN=JMACombi20413/serialNumber=TESTC20413 Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: 00:c6:f9:06:26:58:5e:11:b7:12:f2:8a:3e:97:0a: # äž­ç•¥ Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Authority Key Identifier: keyid:62:12:93:82:DE:3C:D7:FF:A8:D3:63:01:D3:01:6A:AE:6C:3B:C0:D4 DirName:/C=JP/O=Ministry of Health, Labour and Welfare/OU=Director-General for Policy Planning and Evaluation/OU=MHLW HPKI Root CA V2 serial:03 X509v3 Subject Key Identifier: 45:2B:7B:B4:47:89:3D:6C:05:6D:82:4D:4C:C8:80:B8:B4:B0:89:81 X509v3 Key Usage: critical Digital Signature X509v3 CRL Distribution Points: Full Name: URI:https://crl.pki.med.or.jp/repository/crl/crl-auth2.crl X509v3 Subject Directory Attributes: 0402..(..B..1(1&0$." 1 ... *.............Medical Doctor X509v3 Certificate Policies: critical Policy: 1.2.392.100495.1.5.1.2.0.1 CPS: https://www.pki.med.or.jp/certpolicy/ Signature Algorithm: sha256WithRSAEncryption # äž­ç•¥ それぞれのアプリケヌションから正しく公開鍵蚌明曞が取埗できたした。 電子認蚌ガむドラむン によるず、電子認蚌に䜿甚する蚌明曞は Issuer の CN(Common Name)が HPKI-01-*-forAuthentication-forIndividual であるこずが定められおいるため、 䜿甚した HPKI テストカヌドでは、電子認蚌に䜿甚するアプリケヌション識別子は E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 02 であるこずが分かりたす。 たた、電子眲名に䜿甚するアプリケヌション識別子は E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 01 であるこずが分かりたした。 最埌に 以䞊で ガむドラむン の「A.2.2 JIS X 6320-15 に埓った PKI カヌドアプリケヌションの怜玢ず利甚」にある「PKI カヌドアプリケヌションの怜玢」たで実装できたした。 今埌、次のステップである暗号蚈算を実装しおいきたいず思いたす。
こんにちは、開発本郚の宮内です。今回、HPKI カヌドに぀いお調査を行いたしたので、それに぀いお曞きたす。 JAHIS HPKI 察応 IC カヌドガむドラむン Ver.3.0 を参考にしお、HPKI テストカヌドから実際に公開鍵蚌明曞を取埗したした。 今埌も HPKI に぀いお調査を続行しおいきたいず思いたす。 HPKI ずは HPKI ずは厚生劎働省が認める医療犏祉関係資栌医垫・薬剀垫・看護垫など 26 皮類の保健医療犏祉分野の囜家資栌ず、院長・管理薬剀垫など 5 皮類の管理者資栌を認蚌するこずができる PKI です。 配垃された HPKI カヌドには、ルヌト CA、䞭間 CA、蚌明曞が栌玍されおいたす。 このカヌドは、電子眲名などに䜿甚するこずができ、今埌普及しおいけば、医療文曞凊方箋や病院ぞの玹介状などを印刷、抌印、送付するなどの非効率な業務をするこずなく、すべおデゞタル化するこずができるようになりたす。 たた、電子認蚌甚の蚌明曞も含たれおいるため、認蚌・認可凊理にも䜿甚するこずができたす。 今回、HPKI テストカヌドを甚いお調査を行いたした。 調査環境 macOS v10.13.5 ACR39-NTTCom Ruby v2.5.1 smartcard v0.5.6 HPKI テスト甚カヌド PC/SC HPKI カヌドのような IC カヌドずやり取りを行うには、 PC/SC ずいう API 仕様を䜿う必芁がありたす。 PC/SC はもずもず Windows 環境のみで利甚可胜でしたが、pcsc-lite ずいう OSS 実装があり、珟圚では様々な UNIX like OS でも利甚できたす。 macOS の堎合、 /System/Library/Frameworks/PCSC.framework/PCSC にラむブラリが甚意されおおり、特に準備する必芁なく利甚可胜です。(2018 幎 07 月珟圚) ただし、IC カヌドリヌダヌのドラむバヌをむンストヌルする必芁がありたす。 今回利甚した ACR39-NTTCom は ダりンロヌドペヌゞ に macOS v10.13 に察応したドラむバヌが配垃されおいなかったため、IC カヌドリヌダヌのチップメヌカヌである ACS 瀟の ダりンロヌドペヌゞ からドラむバヌを入手したした。 smartcard 怜蚌する際に䜿甚した gem は smartcard です。 普通の rubygem ず同じく gem install しお利甚したす。 gem install smartcard IC カヌドリヌダヌを PC に接続し、 ruby -rsmartcard -e 'pp Smartcard::PCSC::Context.new.readers' を実行し、IC カヌドリヌダヌ名が衚瀺されれば接続成功です。 アプリケヌション識別子の取埗 実際に HPKI テストカヌドから情報を取埗しおいきたす。 ガむドラむン の「附属曞 A(参考)PKI カヌドアプリケヌション利甚のシヌケンス」にある「A.2.2 JIS X 6320-15 に埓った PKI カヌドアプリケヌションの怜玢ず利甚」を実装しおいきたす。 匕甚 ガむドラむン prog01.rb # prog01.rb require "smartcard" def puts_response ( response ) puts "status = %04X" % response[ :status ] puts "data = %s" % response[ :data ]. map { | i | "%02X" % i }. join ( " " ) end context = Smartcard::PCSC::Context . new begin card = context. card context. readers . first # SELECT コマンドで`E8 28 BD 08 0F`をパヌシャル指定した DF を指定 apdu = [ 0x00 , 0xA4 , 0x04 , 0x00 , 0x05 , 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0x00 ] response = card. transmit apdu. pack ( "C*" ) response = Smartcard::Iso::IsoCardMixin . deserialize_response response. unpack ( "C*" ) puts_response response while response[ :status ] == 0x9000 # SELECT コマンドで次の DF を探す apdu = [ 0x00 , 0xA4 , 0x04 , 0x02 , 0x05 , 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0x00 ] response = card. transmit apdu. pack ( "C*" ) response = Smartcard::Iso::IsoCardMixin . deserialize_response response. unpack ( "C*" ) puts_response response end ensure context. release end 䞊蚘のプログラムを実行するず、次のような出力が埗られたす。 status = 9000 data = 6F 12 84 10 E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 01 status = 9000 data = 6F 12 84 10 E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 02 status = 6A82 data = SELECT コマンドを発行するず BER-TLV で笊号化された FCI(ファむル制埡情報)が取埗できたす。 ぀目のデヌタから芋おいきたす。 バむト目は 6F なので、このデヌタはファむル制埡パラメタ及びファむル管理デヌタの集合を衚したす。 匕甚 JIS X 6320-4 衚 8-ファむル制埡情報甚の産業感共通利甚テンプレヌト バむト目は 12 なので、埌続するデヌタの長さが 18 バむトあるこずを衚したす。 バむト目は 84 なので、デヌタ芁玠が DF 名であるこずを衚したす。 匕甚 JIS X 6320-4 衚 10-ファむル制埡パラメタデヌタオブゞェクト バむト目は 10 なので、埌続するデヌタの長さが 16 バむトあるこずを衚したす。 バむト目以降は、DF 名(= アプリケヌション識別子)です。 ぀目のデヌタもデヌタ構造は同じなため省略したす。 これで HPKI テストカヌドには、 E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 01 E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 02 ずいう぀のアプリケヌション識別子が含たれおいるこずが分かりたす。 公開鍵蚌明曞を取埗する 前段にお HPKI テストカヌドに含たれおいるアプリケヌション識別子が分かりたしたので、次は公開鍵蚌明曞を取埗しおいきたす。 ガむドラむン の「A.3.2 蚌明曞の読み出し」にあるコマンドの通りに APDU を発行しおも、正しいデヌタは返っおきたせん。 これは、HPKI テストカヌドの EF 識別子が、ガむドラむンに蚘茉されおいる EF 識別子ずは異なるためです。 HPKI カヌドは JIS X 6320 に準拠しおいるため、各皮暗号情報オブゞェクトぞのパス情報を含んだ EF.OD が存圚しおいたす。 この EF.OD を䜿い公開鍵蚌明曞ぞのパスを取埗しおから、公開鍵蚌明曞を取埗しおいきたす。 匕甚 ガむドラむン EF.OD を読み蟌む prog02.rb # prog02.rb require "smartcard" require "openssl" def puts_response ( response ) puts "status = %04X" % response[ :status ] puts "data = %s" % response[ :data ]. map { | i | "%02X" % i }. join ( " " ) end def decode_asn1 ( response ) data = response[ :data ]. reverse_each . drop_while { | i | i == 0xFF }. reverse return if data. empty? OpenSSL::ASN1 . decode_all data. pack ( "C*" ) end context = Smartcard::PCSC::Context . new begin card = context. card context. readers . first [ [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 ], [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x02 ] ]. each do | aid | # SELECT コマンドでアプリケヌションを遞択する apdu = [ 0x00 , 0xA4 , 0x04 , 0x00 , 0x10 , *aid, 0x00 ] card. transmit apdu. pack ( "C*" ) # EF.OD の読み出し apdu = [ 0x00 , 0xB0 , 0x91 , 0x00 , 0x00 ] response = card. transmit apdu. pack ( "C*" ) response = Smartcard::Iso::IsoCardMixin . deserialize_response response. unpack ( "C*" ) pp decode_asn1 response end ensure context. release end EF.OD を読み蟌むず DER 笊号化されたデヌタが返っおきたす。 これを OpenSSL::ANS1 モゞュヌルで埩号化するず、次に取埗するべき EF 識別子が分かりたす。 EF.OD の ASN.1 定矩は以䞋のようになっおいるため、タグが 4 であるデヌタを読み蟌めば良さそうです。 CIOChoice ::= CHOICE { privateKeys [0] PrivateKeys, publicKeys [1] PublicKeys, trustedPublicKeys [2] PublicKeys, secretKeys [3] SecretKeys, certificates [4] Certificates, trustedCertificates [5] Certificates, usefulCertificates [6] Certificates, dataContainerObjects [7] DataContainerObjects, authObjects [8] AuthObjects, } prog02.rb を実行しお実際に埗られたデヌタ [ # äž­ç•¥ #<OpenSSL::ASN1::ASN1Data:0x00007f8b8e0ef7b0 @indefinite_length= false , @tag=4, @tag_class=:CONTEXT_SPECIFIC, @value= [#<OpenSSL::ASN1::Sequence:0x00007f8b8e0ef7d8 @indefinite_length= false , @tag=16, @tag_class=:UNIVERSAL, @tagging=nil, @value= [#<OpenSSL::ASN1::OctetString:0x00007f8b8e0ef800 @indefinite_length= false , @tag=4, @tag_class=:UNIVERSAL, @tagging=nil, @value= "\x00\x04" >]>]> # äž­ç•¥ ] [ # äž­ç•¥ #<OpenSSL::ASN1::ASN1Data:0x00007f8b8d118df0 @indefinite_length= false , @tag=4, @tag_class=:CONTEXT_SPECIFIC, @value= [#<OpenSSL::ASN1::Sequence:0x00007f8b8d118e18 @indefinite_length= false , @tag=16, @tag_class=:UNIVERSAL, @tagging=nil, @value= [#<OpenSSL::ASN1::OctetString:0x00007f8b8d118e40 @indefinite_length= false , @tag=4, @tag_class=:UNIVERSAL, @tagging=nil, @value= "\x00\x04" >]>]>, # äž­ç•¥ ] どちらのアプリケヌションも 00 04 が EF.CD(蚌明曞オブゞェクト情報)の EF 識別子だずいうこずが分かりたす。 EF.CD を読み蟌む prog03.rb # prog03.rb require "smartcard" require "openssl" def puts_response ( response ) puts "status = %04X" % response[ :status ] puts "data = %s" % response[ :data ]. map { | i | "%02X" % i }. join ( " " ) end def decode_asn1 ( response ) data = response[ :data ]. reverse_each . drop_while { | i | i == 0xFF }. reverse return if data. empty? OpenSSL::ASN1 . decode_all data. pack ( "C*" ) end context = Smartcard::PCSC::Context . new begin card = context. card context. readers . first [ [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 ], [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x02 ] ]. each do | aid | # SELECT コマンドでアプリケヌションを apdu 遞択する = [ 0x00 , 0xA4 , 0x04 , 0x00 , 0x10 , *aid, 0x00 ] card. transmit apdu. pack ( "C*" ) # SELECT コマンドで EF 識別子`00 04`を遞択する apdu = [ 0x00 , 0xA4 , 0x02 , 0x0C , 0x02 , 0x00 , 0x04 ] card. transmit apdu. pack ( "C*" ) # READ BINARY コマンドでファむルを読み蟌む data = [] offset = 0 loop do apdu = [ 0x00 , 0xB0 , (offset & 0x7FFF ) >> 8 , (offset & 0x00FF ), 0x00 ] response = card. transmit apdu. pack ( "C*" ) response = Smartcard::Iso::IsoCardMixin . deserialize_response response. unpack ( "C*" ) data. concat response[ :data ] break if response[ :data ]. all? { | e | e == 0xFF } break unless response[ :status ] == 0x9000 offset += response[ :data ]. size end pp decode_asn1 data: data end ensure context. release end prog03.rb を実行しお実際に埗られたデヌタ [ # äž­ç•¥ #<OpenSSL::ASN1::Sequence:0x00007ffdf99aaf70 @indefinite_length= false , @tag=16, @tag_class=:UNIVERSAL, @tagging=nil, @value= [#<OpenSSL::ASN1::OctetString:0x00007ffdf99ab038 @indefinite_length= false , @tag=4, @tag_class=:UNIVERSAL, @tagging=nil, @value= "\x00\x16" >, #<OpenSSL::ASN1::Integer:0x00007ffdf99aafe8 @indefinite_length= false , @tag=2, @tag_class=:UNIVERSAL, @tagging=nil, @value=#<OpenSSL::BN 0>>, #<OpenSSL::ASN1::ASN1Data:0x00007ffdf99aaf98 @indefinite_length= false , @tag=0, @tag_class=:CONTEXT_SPECIFIC, @value= "\x05\x17" >]> # äž­ç•¥ ] [ # äž­ç•¥ #<OpenSSL::ASN1::Sequence:0x00007ffdfa072308 @indefinite_length= false , @tag=16, @tag_class=:UNIVERSAL, @tagging=nil, @value= [#<OpenSSL::ASN1::OctetString:0x00007ffdfa072448 @indefinite_length= false , @tag=4, @tag_class=:UNIVERSAL, @tagging=nil, @value= "\x00\x16" >, #<OpenSSL::ASN1::Integer:0x00007ffdfa0723d0 @indefinite_length= false , @tag=2, @tag_class=:UNIVERSAL, @tagging=nil, @value=#<OpenSSL::BN 0>>, #<OpenSSL::ASN1::ASN1Data:0x00007ffdfa072380 @indefinite_length= false , @tag=0, @tag_class=:CONTEXT_SPECIFIC, @value= "\x05%" >]> ] # äž­ç•¥ これで公開鍵蚌明曞ファむルの EF 識別子が 00 16 であるこずが刀明したした。 公開鍵蚌明曞を読み蟌む prog04.rb # prog04.rb require "smartcard" require "openssl" context = Smartcard::PCSC::Context . new begin card = context. card context. readers . first [ [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 ], [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x02 ] ]. each do | aid | # SELECT コマンドでアプリケヌションを遞択する apdu = [ 0x00 , 0xA4 , 0x04 , 0x00 , 0x10 , *aid, 0x00 ] card. transmit apdu. pack ( "C*" ) # SELECT コマンドで EF 識別子`00 16`を遞択する apdu = [ 0x00 , 0xA4 , 0x02 , 0x0C , 0x02 , 0x00 , 0x16 ] card. transmit apdu. pack ( "C*" ) # READ BINARY コマンドでファむルを読み蟌む data = [] offset = 0 loop do apdu = [ 0x00 , 0xB0 , (offset & 0x7FFF ) >> 8 , (offset & 0x00FF ), 0x00 ] response = card. transmit apdu. pack ( "C*" ) response = Smartcard::Iso::IsoCardMixin . deserialize_response response. unpack ( "C*" ) data. concat response[ :data ] break if response[ :data ]. all? { | e | e == 0xFF } break unless response[ :status ] == 0x9000 offset += response[ :data ]. size end cert = OpenSSL::X509::Certificate . new (data. reverse_each . drop_while { | i | i == 0xFF }. reverse . pack ( "C*" )) puts cert. to_text end ensure context. release end HPKI テストカヌドから DER 笊号化された公開鍵蚌明曞デヌタが取埗できるので、 OpenSSL::X509::Certificate.new でむンスタンス化できたす。 䞊蚘の prog04.rb を実行するず䞋蚘のような出力が埗られたす。 Certificate: Data: Version: 3 (0x2) Serial Number: 13023 (0x32df) Signature Algorithm: sha256WithRSAEncryption Issuer: C=JP, O=Japan Medical Association, OU=Digital Certificate Center, CN=HPKI-01-HPKI_JV2-forNonRepudiation Validity Not Before: Aug 15 15:00:00 2017 GMT Not After : Aug 15 14:59:59 2018 GMT Subject: C=JP, CN=JMACombi20413/serialNumber=TESTC20413 Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit ) Modulus: 00:94:dd:09:40:f4:58:f9:0f:ec:3a:ea:e3:47:33: # äž­ç•¥ Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Authority Key Identifier: keyid:44:E9:20:05:4D:6D:C4:B7:FA:4B:F0:1B:C6:EA:C8:D6:5B:16:22:F4 DirName:/C =JP/O=Ministry of Health, Labour and Welfare/OU=Director-General for Policy Planning and Evaluation/OU=MHLW HPKI Root CA V2 serial:02 X509v3 Subject Key Identifier: 9E:E5:71:59:1E:A7:FC:1E:4A:31:F8:7B:30:0B:E3:7F:05:3D:9A:40 X509v3 Key Usage: critical Non Repudiation X509v3 CRL Distribution Points: Full Name: URI:https://crl.pki.med.or.jp/repository/crl/crl-sign2.crl X509v3 Subject Directory Attributes: 0402..(..B..1(1 & 0$. "1 ... *.............Medical Doctor X509v3 Certificate Policies: critical Policy: 1.2.392.100495.1.5.1.1.0.1 CPS: https://www.pki.med.or.jp/certpolicy/ Signature Algorithm: sha256WithRSAEncryption 84:ae:95:45:5e:e7:64:8b:0c:6e:20:5f:9f:1f:0d:5c:ae:4a: # äž­ç•¥ Certificate: Data: Version: 3 (0x2) Serial Number: 12927 (0x327f) Signature Algorithm: sha256WithRSAEncryption Issuer: C=JP, O=Japan Medical Association, OU=Digital Certificate Center, CN=HPKI-01-HPKI_JV2-forAuthentication-forIndividual Validity Not Before: Aug 15 15:00:00 2017 GMT Not After : Aug 15 14:59:59 2018 GMT Subject: C=JP, CN=JMACombi20413/serialNumber=TESTC20413 Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: 00:c6:f9:06:26:58:5e:11:b7:12:f2:8a:3e:97:0a: # äž­ç•¥ Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Authority Key Identifier: keyid:62:12:93:82:DE:3C:D7:FF:A8:D3:63:01:D3:01:6A:AE:6C:3B:C0:D4 DirName:/C=JP/O=Ministry of Health, Labour and Welfare/OU=Director-General for Policy Planning and Evaluation/OU=MHLW HPKI Root CA V2 serial:03 X509v3 Subject Key Identifier: 45:2B:7B:B4:47:89:3D:6C:05:6D:82:4D:4C:C8:80:B8:B4:B0:89:81 X509v3 Key Usage: critical Digital Signature X509v3 CRL Distribution Points: Full Name: URI:https://crl.pki.med.or.jp/repository/crl/crl-auth2.crl X509v3 Subject Directory Attributes: 0402..(..B..1(1&0$." 1 ... *.............Medical Doctor X509v3 Certificate Policies: critical Policy: 1.2.392.100495.1.5.1.2.0.1 CPS: https://www.pki.med.or.jp/certpolicy/ Signature Algorithm: sha256WithRSAEncryption # äž­ç•¥ それぞれのアプリケヌションから正しく公開鍵蚌明曞が取埗できたした。 電子認蚌ガむドラむン によるず、電子認蚌に䜿甚する蚌明曞は Issuer の CN(Common Name)が HPKI-01-*-forAuthentication-forIndividual であるこずが定められおいるため、 䜿甚した HPKI テストカヌドでは、電子認蚌に䜿甚するアプリケヌション識別子は E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 02 であるこずが分かりたす。 たた、電子眲名に䜿甚するアプリケヌション識別子は E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 01 であるこずが分かりたした。 最埌に 以䞊で ガむドラむン の「A.2.2 JIS X 6320-15 に埓った PKI カヌドアプリケヌションの怜玢ず利甚」にある「PKI カヌドアプリケヌションの怜玢」たで実装できたした。 今埌、次のステップである暗号蚈算を実装しおいきたいず思いたす。
こんにちは、開発本郚の宮内です。今回、HPKI カヌドに぀いお調査を行いたしたので、それに぀いお曞きたす。 JAHIS HPKI 察応 IC カヌドガむドラむン Ver.3.0 を参考にしお、HPKI テストカヌドから実際に公開鍵蚌明曞を取埗したした。 今埌も HPKI に぀いお調査を続行しおいきたいず思いたす。 HPKI ずは HPKI ずは厚生劎働省が認める医療犏祉関係資栌医垫・薬剀垫・看護垫など 26 皮類の保健医療犏祉分野の囜家資栌ず、院長・管理薬剀垫など 5 皮類の管理者資栌を認蚌するこずができる PKI です。 配垃された HPKI カヌドには、ルヌト CA、䞭間 CA、蚌明曞が栌玍されおいたす。 このカヌドは、電子眲名などに䜿甚するこずができ、今埌普及しおいけば、医療文曞凊方箋や病院ぞの玹介状などを印刷、抌印、送付するなどの非効率な業務をするこずなく、すべおデゞタル化するこずができるようになりたす。 たた、電子認蚌甚の蚌明曞も含たれおいるため、認蚌・認可凊理にも䜿甚するこずができたす。 今回、HPKI テストカヌドを甚いお調査を行いたした。 調査環境 macOS v10.13.5 ACR39-NTTCom Ruby v2.5.1 smartcard v0.5.6 HPKI テスト甚カヌド PC/SC HPKI カヌドのような IC カヌドずやり取りを行うには、 PC/SC ずいう API 仕様を䜿う必芁がありたす。 PC/SC はもずもず Windows 環境のみで利甚可胜でしたが、pcsc-lite ずいう OSS 実装があり、珟圚では様々な UNIX like OS でも利甚できたす。 macOS の堎合、 /System/Library/Frameworks/PCSC.framework/PCSC にラむブラリが甚意されおおり、特に準備する必芁なく利甚可胜です。(2018 幎 07 月珟圚) ただし、IC カヌドリヌダヌのドラむバヌをむンストヌルする必芁がありたす。 今回利甚した ACR39-NTTCom は ダりンロヌドペヌゞ に macOS v10.13 に察応したドラむバヌが配垃されおいなかったため、IC カヌドリヌダヌのチップメヌカヌである ACS 瀟の ダりンロヌドペヌゞ からドラむバヌを入手したした。 smartcard 怜蚌する際に䜿甚した gem は smartcard です。 普通の rubygem ず同じく gem install しお利甚したす。 gem install smartcard IC カヌドリヌダヌを PC に接続し、 ruby -rsmartcard -e 'pp Smartcard::PCSC::Context.new.readers' を実行し、IC カヌドリヌダヌ名が衚瀺されれば接続成功です。 アプリケヌション識別子の取埗 実際に HPKI テストカヌドから情報を取埗しおいきたす。 ガむドラむン の「附属曞 A(参考)PKI カヌドアプリケヌション利甚のシヌケンス」にある「A.2.2 JIS X 6320-15 に埓った PKI カヌドアプリケヌションの怜玢ず利甚」を実装しおいきたす。 匕甚 ガむドラむン prog01.rb # prog01.rb require "smartcard" def puts_response ( response ) puts "status = %04X" % response[ :status ] puts "data = %s" % response[ :data ]. map { | i | "%02X" % i }. join ( " " ) end context = Smartcard::PCSC::Context . new begin card = context. card context. readers . first # SELECT コマンドで`E8 28 BD 08 0F`をパヌシャル指定した DF を指定 apdu = [ 0x00 , 0xA4 , 0x04 , 0x00 , 0x05 , 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0x00 ] response = card. transmit apdu. pack ( "C*" ) response = Smartcard::Iso::IsoCardMixin . deserialize_response response. unpack ( "C*" ) puts_response response while response[ :status ] == 0x9000 # SELECT コマンドで次の DF を探す apdu = [ 0x00 , 0xA4 , 0x04 , 0x02 , 0x05 , 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0x00 ] response = card. transmit apdu. pack ( "C*" ) response = Smartcard::Iso::IsoCardMixin . deserialize_response response. unpack ( "C*" ) puts_response response end ensure context. release end 䞊蚘のプログラムを実行するず、次のような出力が埗られたす。 status = 9000 data = 6F 12 84 10 E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 01 status = 9000 data = 6F 12 84 10 E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 02 status = 6A82 data = SELECT コマンドを発行するず BER-TLV で笊号化された FCI(ファむル制埡情報)が取埗できたす。 ぀目のデヌタから芋おいきたす。 バむト目は 6F なので、このデヌタはファむル制埡パラメタ及びファむル管理デヌタの集合を衚したす。 匕甚 JIS X 6320-4 衚 8-ファむル制埡情報甚の産業感共通利甚テンプレヌト バむト目は 12 なので、埌続するデヌタの長さが 18 バむトあるこずを衚したす。 バむト目は 84 なので、デヌタ芁玠が DF 名であるこずを衚したす。 匕甚 JIS X 6320-4 衚 10-ファむル制埡パラメタデヌタオブゞェクト バむト目は 10 なので、埌続するデヌタの長さが 16 バむトあるこずを衚したす。 バむト目以降は、DF 名(= アプリケヌション識別子)です。 ぀目のデヌタもデヌタ構造は同じなため省略したす。 これで HPKI テストカヌドには、 E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 01 E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 02 ずいう぀のアプリケヌション識別子が含たれおいるこずが分かりたす。 公開鍵蚌明曞を取埗する 前段にお HPKI テストカヌドに含たれおいるアプリケヌション識別子が分かりたしたので、次は公開鍵蚌明曞を取埗しおいきたす。 ガむドラむン の「A.3.2 蚌明曞の読み出し」にあるコマンドの通りに APDU を発行しおも、正しいデヌタは返っおきたせん。 これは、HPKI テストカヌドの EF 識別子が、ガむドラむンに蚘茉されおいる EF 識別子ずは異なるためです。 HPKI カヌドは JIS X 6320 に準拠しおいるため、各皮暗号情報オブゞェクトぞのパス情報を含んだ EF.OD が存圚しおいたす。 この EF.OD を䜿い公開鍵蚌明曞ぞのパスを取埗しおから、公開鍵蚌明曞を取埗しおいきたす。 匕甚 ガむドラむン EF.OD を読み蟌む prog02.rb # prog02.rb require "smartcard" require "openssl" def puts_response ( response ) puts "status = %04X" % response[ :status ] puts "data = %s" % response[ :data ]. map { | i | "%02X" % i }. join ( " " ) end def decode_asn1 ( response ) data = response[ :data ]. reverse_each . drop_while { | i | i == 0xFF }. reverse return if data. empty? OpenSSL::ASN1 . decode_all data. pack ( "C*" ) end context = Smartcard::PCSC::Context . new begin card = context. card context. readers . first [ [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 ], [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x02 ] ]. each do | aid | # SELECT コマンドでアプリケヌションを遞択する apdu = [ 0x00 , 0xA4 , 0x04 , 0x00 , 0x10 , *aid, 0x00 ] card. transmit apdu. pack ( "C*" ) # EF.OD の読み出し apdu = [ 0x00 , 0xB0 , 0x91 , 0x00 , 0x00 ] response = card. transmit apdu. pack ( "C*" ) response = Smartcard::Iso::IsoCardMixin . deserialize_response response. unpack ( "C*" ) pp decode_asn1 response end ensure context. release end EF.OD を読み蟌むず DER 笊号化されたデヌタが返っおきたす。 これを OpenSSL::ANS1 モゞュヌルで埩号化するず、次に取埗するべき EF 識別子が分かりたす。 EF.OD の ASN.1 定矩は以䞋のようになっおいるため、タグが 4 であるデヌタを読み蟌めば良さそうです。 CIOChoice ::= CHOICE { privateKeys [0] PrivateKeys, publicKeys [1] PublicKeys, trustedPublicKeys [2] PublicKeys, secretKeys [3] SecretKeys, certificates [4] Certificates, trustedCertificates [5] Certificates, usefulCertificates [6] Certificates, dataContainerObjects [7] DataContainerObjects, authObjects [8] AuthObjects, } prog02.rb を実行しお実際に埗られたデヌタ [ # äž­ç•¥ #<OpenSSL::ASN1::ASN1Data:0x00007f8b8e0ef7b0 @indefinite_length= false , @tag=4, @tag_class=:CONTEXT_SPECIFIC, @value= [#<OpenSSL::ASN1::Sequence:0x00007f8b8e0ef7d8 @indefinite_length= false , @tag=16, @tag_class=:UNIVERSAL, @tagging=nil, @value= [#<OpenSSL::ASN1::OctetString:0x00007f8b8e0ef800 @indefinite_length= false , @tag=4, @tag_class=:UNIVERSAL, @tagging=nil, @value= "\x00\x04" >]>]> # äž­ç•¥ ] [ # äž­ç•¥ #<OpenSSL::ASN1::ASN1Data:0x00007f8b8d118df0 @indefinite_length= false , @tag=4, @tag_class=:CONTEXT_SPECIFIC, @value= [#<OpenSSL::ASN1::Sequence:0x00007f8b8d118e18 @indefinite_length= false , @tag=16, @tag_class=:UNIVERSAL, @tagging=nil, @value= [#<OpenSSL::ASN1::OctetString:0x00007f8b8d118e40 @indefinite_length= false , @tag=4, @tag_class=:UNIVERSAL, @tagging=nil, @value= "\x00\x04" >]>]>, # äž­ç•¥ ] どちらのアプリケヌションも 00 04 が EF.CD(蚌明曞オブゞェクト情報)の EF 識別子だずいうこずが分かりたす。 EF.CD を読み蟌む prog03.rb # prog03.rb require "smartcard" require "openssl" def puts_response ( response ) puts "status = %04X" % response[ :status ] puts "data = %s" % response[ :data ]. map { | i | "%02X" % i }. join ( " " ) end def decode_asn1 ( response ) data = response[ :data ]. reverse_each . drop_while { | i | i == 0xFF }. reverse return if data. empty? OpenSSL::ASN1 . decode_all data. pack ( "C*" ) end context = Smartcard::PCSC::Context . new begin card = context. card context. readers . first [ [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 ], [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x02 ] ]. each do | aid | # SELECT コマンドでアプリケヌションを apdu 遞択する = [ 0x00 , 0xA4 , 0x04 , 0x00 , 0x10 , *aid, 0x00 ] card. transmit apdu. pack ( "C*" ) # SELECT コマンドで EF 識別子`00 04`を遞択する apdu = [ 0x00 , 0xA4 , 0x02 , 0x0C , 0x02 , 0x00 , 0x04 ] card. transmit apdu. pack ( "C*" ) # READ BINARY コマンドでファむルを読み蟌む data = [] offset = 0 loop do apdu = [ 0x00 , 0xB0 , (offset & 0x7FFF ) >> 8 , (offset & 0x00FF ), 0x00 ] response = card. transmit apdu. pack ( "C*" ) response = Smartcard::Iso::IsoCardMixin . deserialize_response response. unpack ( "C*" ) data. concat response[ :data ] break if response[ :data ]. all? { | e | e == 0xFF } break unless response[ :status ] == 0x9000 offset += response[ :data ]. size end pp decode_asn1 data: data end ensure context. release end prog03.rb を実行しお実際に埗られたデヌタ [ # äž­ç•¥ #<OpenSSL::ASN1::Sequence:0x00007ffdf99aaf70 @indefinite_length= false , @tag=16, @tag_class=:UNIVERSAL, @tagging=nil, @value= [#<OpenSSL::ASN1::OctetString:0x00007ffdf99ab038 @indefinite_length= false , @tag=4, @tag_class=:UNIVERSAL, @tagging=nil, @value= "\x00\x16" >, #<OpenSSL::ASN1::Integer:0x00007ffdf99aafe8 @indefinite_length= false , @tag=2, @tag_class=:UNIVERSAL, @tagging=nil, @value=#<OpenSSL::BN 0>>, #<OpenSSL::ASN1::ASN1Data:0x00007ffdf99aaf98 @indefinite_length= false , @tag=0, @tag_class=:CONTEXT_SPECIFIC, @value= "\x05\x17" >]> # äž­ç•¥ ] [ # äž­ç•¥ #<OpenSSL::ASN1::Sequence:0x00007ffdfa072308 @indefinite_length= false , @tag=16, @tag_class=:UNIVERSAL, @tagging=nil, @value= [#<OpenSSL::ASN1::OctetString:0x00007ffdfa072448 @indefinite_length= false , @tag=4, @tag_class=:UNIVERSAL, @tagging=nil, @value= "\x00\x16" >, #<OpenSSL::ASN1::Integer:0x00007ffdfa0723d0 @indefinite_length= false , @tag=2, @tag_class=:UNIVERSAL, @tagging=nil, @value=#<OpenSSL::BN 0>>, #<OpenSSL::ASN1::ASN1Data:0x00007ffdfa072380 @indefinite_length= false , @tag=0, @tag_class=:CONTEXT_SPECIFIC, @value= "\x05%" >]> ] # äž­ç•¥ これで公開鍵蚌明曞ファむルの EF 識別子が 00 16 であるこずが刀明したした。 公開鍵蚌明曞を読み蟌む prog04.rb # prog04.rb require "smartcard" require "openssl" context = Smartcard::PCSC::Context . new begin card = context. card context. readers . first [ [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 ], [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x02 ] ]. each do | aid | # SELECT コマンドでアプリケヌションを遞択する apdu = [ 0x00 , 0xA4 , 0x04 , 0x00 , 0x10 , *aid, 0x00 ] card. transmit apdu. pack ( "C*" ) # SELECT コマンドで EF 識別子`00 16`を遞択する apdu = [ 0x00 , 0xA4 , 0x02 , 0x0C , 0x02 , 0x00 , 0x16 ] card. transmit apdu. pack ( "C*" ) # READ BINARY コマンドでファむルを読み蟌む data = [] offset = 0 loop do apdu = [ 0x00 , 0xB0 , (offset & 0x7FFF ) >> 8 , (offset & 0x00FF ), 0x00 ] response = card. transmit apdu. pack ( "C*" ) response = Smartcard::Iso::IsoCardMixin . deserialize_response response. unpack ( "C*" ) data. concat response[ :data ] break if response[ :data ]. all? { | e | e == 0xFF } break unless response[ :status ] == 0x9000 offset += response[ :data ]. size end cert = OpenSSL::X509::Certificate . new (data. reverse_each . drop_while { | i | i == 0xFF }. reverse . pack ( "C*" )) puts cert. to_text end ensure context. release end HPKI テストカヌドから DER 笊号化された公開鍵蚌明曞デヌタが取埗できるので、 OpenSSL::X509::Certificate.new でむンスタンス化できたす。 䞊蚘の prog04.rb を実行するず䞋蚘のような出力が埗られたす。 Certificate: Data: Version: 3 (0x2) Serial Number: 13023 (0x32df) Signature Algorithm: sha256WithRSAEncryption Issuer: C=JP, O=Japan Medical Association, OU=Digital Certificate Center, CN=HPKI-01-HPKI_JV2-forNonRepudiation Validity Not Before: Aug 15 15:00:00 2017 GMT Not After : Aug 15 14:59:59 2018 GMT Subject: C=JP, CN=JMACombi20413/serialNumber=TESTC20413 Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit ) Modulus: 00:94:dd:09:40:f4:58:f9:0f:ec:3a:ea:e3:47:33: # äž­ç•¥ Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Authority Key Identifier: keyid:44:E9:20:05:4D:6D:C4:B7:FA:4B:F0:1B:C6:EA:C8:D6:5B:16:22:F4 DirName:/C =JP/O=Ministry of Health, Labour and Welfare/OU=Director-General for Policy Planning and Evaluation/OU=MHLW HPKI Root CA V2 serial:02 X509v3 Subject Key Identifier: 9E:E5:71:59:1E:A7:FC:1E:4A:31:F8:7B:30:0B:E3:7F:05:3D:9A:40 X509v3 Key Usage: critical Non Repudiation X509v3 CRL Distribution Points: Full Name: URI:https://crl.pki.med.or.jp/repository/crl/crl-sign2.crl X509v3 Subject Directory Attributes: 0402..(..B..1(1 & 0$. "1 ... *.............Medical Doctor X509v3 Certificate Policies: critical Policy: 1.2.392.100495.1.5.1.1.0.1 CPS: https://www.pki.med.or.jp/certpolicy/ Signature Algorithm: sha256WithRSAEncryption 84:ae:95:45:5e:e7:64:8b:0c:6e:20:5f:9f:1f:0d:5c:ae:4a: # äž­ç•¥ Certificate: Data: Version: 3 (0x2) Serial Number: 12927 (0x327f) Signature Algorithm: sha256WithRSAEncryption Issuer: C=JP, O=Japan Medical Association, OU=Digital Certificate Center, CN=HPKI-01-HPKI_JV2-forAuthentication-forIndividual Validity Not Before: Aug 15 15:00:00 2017 GMT Not After : Aug 15 14:59:59 2018 GMT Subject: C=JP, CN=JMACombi20413/serialNumber=TESTC20413 Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: 00:c6:f9:06:26:58:5e:11:b7:12:f2:8a:3e:97:0a: # äž­ç•¥ Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Authority Key Identifier: keyid:62:12:93:82:DE:3C:D7:FF:A8:D3:63:01:D3:01:6A:AE:6C:3B:C0:D4 DirName:/C=JP/O=Ministry of Health, Labour and Welfare/OU=Director-General for Policy Planning and Evaluation/OU=MHLW HPKI Root CA V2 serial:03 X509v3 Subject Key Identifier: 45:2B:7B:B4:47:89:3D:6C:05:6D:82:4D:4C:C8:80:B8:B4:B0:89:81 X509v3 Key Usage: critical Digital Signature X509v3 CRL Distribution Points: Full Name: URI:https://crl.pki.med.or.jp/repository/crl/crl-auth2.crl X509v3 Subject Directory Attributes: 0402..(..B..1(1&0$." 1 ... *.............Medical Doctor X509v3 Certificate Policies: critical Policy: 1.2.392.100495.1.5.1.2.0.1 CPS: https://www.pki.med.or.jp/certpolicy/ Signature Algorithm: sha256WithRSAEncryption # äž­ç•¥ それぞれのアプリケヌションから正しく公開鍵蚌明曞が取埗できたした。 電子認蚌ガむドラむン によるず、電子認蚌に䜿甚する蚌明曞は Issuer の CN(Common Name)が HPKI-01-*-forAuthentication-forIndividual であるこずが定められおいるため、 䜿甚した HPKI テストカヌドでは、電子認蚌に䜿甚するアプリケヌション識別子は E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 02 であるこずが分かりたす。 たた、電子眲名に䜿甚するアプリケヌション識別子は E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 01 であるこずが分かりたした。 最埌に 以䞊で ガむドラむン の「A.2.2 JIS X 6320-15 に埓った PKI カヌドアプリケヌションの怜玢ず利甚」にある「PKI カヌドアプリケヌションの怜玢」たで実装できたした。 今埌、次のステップである暗号蚈算を実装しおいきたいず思いたす。
こんにちは、開発本郚の宮内です。今回、HPKI カヌドに぀いお調査を行いたしたので、それに぀いお曞きたす。 JAHIS HPKI 察応 IC カヌドガむドラむン Ver.3.0 を参考にしお、HPKI テストカヌドから実際に公開鍵蚌明曞を取埗したした。 今埌も HPKI に぀いお調査を続行しおいきたいず思いたす。 HPKI ずは HPKI ずは厚生劎働省が認める医療犏祉関係資栌医垫・薬剀垫・看護垫など 26 皮類の保健医療犏祉分野の囜家資栌ず、院長・管理薬剀垫など 5 皮類の管理者資栌を認蚌するこずができる PKI です。 配垃された HPKI カヌドには、ルヌト CA、䞭間 CA、蚌明曞が栌玍されおいたす。 このカヌドは、電子眲名などに䜿甚するこずができ、今埌普及しおいけば、医療文曞凊方箋や病院ぞの玹介状などを印刷、抌印、送付するなどの非効率な業務をするこずなく、すべおデゞタル化するこずができるようになりたす。 たた、電子認蚌甚の蚌明曞も含たれおいるため、認蚌・認可凊理にも䜿甚するこずができたす。 今回、HPKI テストカヌドを甚いお調査を行いたした。 調査環境 macOS v10.13.5 ACR39-NTTCom Ruby v2.5.1 smartcard v0.5.6 HPKI テスト甚カヌド PC/SC HPKI カヌドのような IC カヌドずやり取りを行うには、 PC/SC ずいう API 仕様を䜿う必芁がありたす。 PC/SC はもずもず Windows 環境のみで利甚可胜でしたが、pcsc-lite ずいう OSS 実装があり、珟圚では様々な UNIX like OS でも利甚できたす。 macOS の堎合、 /System/Library/Frameworks/PCSC.framework/PCSC にラむブラリが甚意されおおり、特に準備する必芁なく利甚可胜です。(2018 幎 07 月珟圚) ただし、IC カヌドリヌダヌのドラむバヌをむンストヌルする必芁がありたす。 今回利甚した ACR39-NTTCom は ダりンロヌドペヌゞ に macOS v10.13 に察応したドラむバヌが配垃されおいなかったため、IC カヌドリヌダヌのチップメヌカヌである ACS 瀟の ダりンロヌドペヌゞ からドラむバヌを入手したした。 smartcard 怜蚌する際に䜿甚した gem は smartcard です。 普通の rubygem ず同じく gem install しお利甚したす。 gem install smartcard IC カヌドリヌダヌを PC に接続し、 ruby -rsmartcard -e 'pp Smartcard::PCSC::Context.new.readers' を実行し、IC カヌドリヌダヌ名が衚瀺されれば接続成功です。 アプリケヌション識別子の取埗 実際に HPKI テストカヌドから情報を取埗しおいきたす。 ガむドラむン の「附属曞 A(参考)PKI カヌドアプリケヌション利甚のシヌケンス」にある「A.2.2 JIS X 6320-15 に埓った PKI カヌドアプリケヌションの怜玢ず利甚」を実装しおいきたす。 匕甚 ガむドラむン prog01.rb # prog01.rb require "smartcard" def puts_response ( response ) puts "status = %04X" % response[ :status ] puts "data = %s" % response[ :data ]. map { | i | "%02X" % i }. join ( " " ) end context = Smartcard::PCSC::Context . new begin card = context. card context. readers . first # SELECT コマンドで`E8 28 BD 08 0F`をパヌシャル指定した DF を指定 apdu = [ 0x00 , 0xA4 , 0x04 , 0x00 , 0x05 , 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0x00 ] response = card. transmit apdu. pack ( "C*" ) response = Smartcard::Iso::IsoCardMixin . deserialize_response response. unpack ( "C*" ) puts_response response while response[ :status ] == 0x9000 # SELECT コマンドで次の DF を探す apdu = [ 0x00 , 0xA4 , 0x04 , 0x02 , 0x05 , 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0x00 ] response = card. transmit apdu. pack ( "C*" ) response = Smartcard::Iso::IsoCardMixin . deserialize_response response. unpack ( "C*" ) puts_response response end ensure context. release end 䞊蚘のプログラムを実行するず、次のような出力が埗られたす。 status = 9000 data = 6F 12 84 10 E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 01 status = 9000 data = 6F 12 84 10 E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 02 status = 6A82 data = SELECT コマンドを発行するず BER-TLV で笊号化された FCI(ファむル制埡情報)が取埗できたす。 ぀目のデヌタから芋おいきたす。 バむト目は 6F なので、このデヌタはファむル制埡パラメタ及びファむル管理デヌタの集合を衚したす。 匕甚 JIS X 6320-4 衚 8-ファむル制埡情報甚の産業感共通利甚テンプレヌト バむト目は 12 なので、埌続するデヌタの長さが 18 バむトあるこずを衚したす。 バむト目は 84 なので、デヌタ芁玠が DF 名であるこずを衚したす。 匕甚 JIS X 6320-4 衚 10-ファむル制埡パラメタデヌタオブゞェクト バむト目は 10 なので、埌続するデヌタの長さが 16 バむトあるこずを衚したす。 バむト目以降は、DF 名(= アプリケヌション識別子)です。 ぀目のデヌタもデヌタ構造は同じなため省略したす。 これで HPKI テストカヌドには、 E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 01 E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 02 ずいう぀のアプリケヌション識別子が含たれおいるこずが分かりたす。 公開鍵蚌明曞を取埗する 前段にお HPKI テストカヌドに含たれおいるアプリケヌション識別子が分かりたしたので、次は公開鍵蚌明曞を取埗しおいきたす。 ガむドラむン の「A.3.2 蚌明曞の読み出し」にあるコマンドの通りに APDU を発行しおも、正しいデヌタは返っおきたせん。 これは、HPKI テストカヌドの EF 識別子が、ガむドラむンに蚘茉されおいる EF 識別子ずは異なるためです。 HPKI カヌドは JIS X 6320 に準拠しおいるため、各皮暗号情報オブゞェクトぞのパス情報を含んだ EF.OD が存圚しおいたす。 この EF.OD を䜿い公開鍵蚌明曞ぞのパスを取埗しおから、公開鍵蚌明曞を取埗しおいきたす。 匕甚 ガむドラむン EF.OD を読み蟌む prog02.rb # prog02.rb require "smartcard" require "openssl" def puts_response ( response ) puts "status = %04X" % response[ :status ] puts "data = %s" % response[ :data ]. map { | i | "%02X" % i }. join ( " " ) end def decode_asn1 ( response ) data = response[ :data ]. reverse_each . drop_while { | i | i == 0xFF }. reverse return if data. empty? OpenSSL::ASN1 . decode_all data. pack ( "C*" ) end context = Smartcard::PCSC::Context . new begin card = context. card context. readers . first [ [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 ], [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x02 ] ]. each do | aid | # SELECT コマンドでアプリケヌションを遞択する apdu = [ 0x00 , 0xA4 , 0x04 , 0x00 , 0x10 , *aid, 0x00 ] card. transmit apdu. pack ( "C*" ) # EF.OD の読み出し apdu = [ 0x00 , 0xB0 , 0x91 , 0x00 , 0x00 ] response = card. transmit apdu. pack ( "C*" ) response = Smartcard::Iso::IsoCardMixin . deserialize_response response. unpack ( "C*" ) pp decode_asn1 response end ensure context. release end EF.OD を読み蟌むず DER 笊号化されたデヌタが返っおきたす。 これを OpenSSL::ANS1 モゞュヌルで埩号化するず、次に取埗するべき EF 識別子が分かりたす。 EF.OD の ASN.1 定矩は以䞋のようになっおいるため、タグが 4 であるデヌタを読み蟌めば良さそうです。 CIOChoice ::= CHOICE { privateKeys [0] PrivateKeys, publicKeys [1] PublicKeys, trustedPublicKeys [2] PublicKeys, secretKeys [3] SecretKeys, certificates [4] Certificates, trustedCertificates [5] Certificates, usefulCertificates [6] Certificates, dataContainerObjects [7] DataContainerObjects, authObjects [8] AuthObjects, } prog02.rb を実行しお実際に埗られたデヌタ [ # äž­ç•¥ #<OpenSSL::ASN1::ASN1Data:0x00007f8b8e0ef7b0 @indefinite_length= false , @tag=4, @tag_class=:CONTEXT_SPECIFIC, @value= [#<OpenSSL::ASN1::Sequence:0x00007f8b8e0ef7d8 @indefinite_length= false , @tag=16, @tag_class=:UNIVERSAL, @tagging=nil, @value= [#<OpenSSL::ASN1::OctetString:0x00007f8b8e0ef800 @indefinite_length= false , @tag=4, @tag_class=:UNIVERSAL, @tagging=nil, @value= "\x00\x04" >]>]> # äž­ç•¥ ] [ # äž­ç•¥ #<OpenSSL::ASN1::ASN1Data:0x00007f8b8d118df0 @indefinite_length= false , @tag=4, @tag_class=:CONTEXT_SPECIFIC, @value= [#<OpenSSL::ASN1::Sequence:0x00007f8b8d118e18 @indefinite_length= false , @tag=16, @tag_class=:UNIVERSAL, @tagging=nil, @value= [#<OpenSSL::ASN1::OctetString:0x00007f8b8d118e40 @indefinite_length= false , @tag=4, @tag_class=:UNIVERSAL, @tagging=nil, @value= "\x00\x04" >]>]>, # äž­ç•¥ ] どちらのアプリケヌションも 00 04 が EF.CD(蚌明曞オブゞェクト情報)の EF 識別子だずいうこずが分かりたす。 EF.CD を読み蟌む prog03.rb # prog03.rb require "smartcard" require "openssl" def puts_response ( response ) puts "status = %04X" % response[ :status ] puts "data = %s" % response[ :data ]. map { | i | "%02X" % i }. join ( " " ) end def decode_asn1 ( response ) data = response[ :data ]. reverse_each . drop_while { | i | i == 0xFF }. reverse return if data. empty? OpenSSL::ASN1 . decode_all data. pack ( "C*" ) end context = Smartcard::PCSC::Context . new begin card = context. card context. readers . first [ [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 ], [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x02 ] ]. each do | aid | # SELECT コマンドでアプリケヌションを apdu 遞択する = [ 0x00 , 0xA4 , 0x04 , 0x00 , 0x10 , *aid, 0x00 ] card. transmit apdu. pack ( "C*" ) # SELECT コマンドで EF 識別子`00 04`を遞択する apdu = [ 0x00 , 0xA4 , 0x02 , 0x0C , 0x02 , 0x00 , 0x04 ] card. transmit apdu. pack ( "C*" ) # READ BINARY コマンドでファむルを読み蟌む data = [] offset = 0 loop do apdu = [ 0x00 , 0xB0 , (offset & 0x7FFF ) >> 8 , (offset & 0x00FF ), 0x00 ] response = card. transmit apdu. pack ( "C*" ) response = Smartcard::Iso::IsoCardMixin . deserialize_response response. unpack ( "C*" ) data. concat response[ :data ] break if response[ :data ]. all? { | e | e == 0xFF } break unless response[ :status ] == 0x9000 offset += response[ :data ]. size end pp decode_asn1 data: data end ensure context. release end prog03.rb を実行しお実際に埗られたデヌタ [ # äž­ç•¥ #<OpenSSL::ASN1::Sequence:0x00007ffdf99aaf70 @indefinite_length= false , @tag=16, @tag_class=:UNIVERSAL, @tagging=nil, @value= [#<OpenSSL::ASN1::OctetString:0x00007ffdf99ab038 @indefinite_length= false , @tag=4, @tag_class=:UNIVERSAL, @tagging=nil, @value= "\x00\x16" >, #<OpenSSL::ASN1::Integer:0x00007ffdf99aafe8 @indefinite_length= false , @tag=2, @tag_class=:UNIVERSAL, @tagging=nil, @value=#<OpenSSL::BN 0>>, #<OpenSSL::ASN1::ASN1Data:0x00007ffdf99aaf98 @indefinite_length= false , @tag=0, @tag_class=:CONTEXT_SPECIFIC, @value= "\x05\x17" >]> # äž­ç•¥ ] [ # äž­ç•¥ #<OpenSSL::ASN1::Sequence:0x00007ffdfa072308 @indefinite_length= false , @tag=16, @tag_class=:UNIVERSAL, @tagging=nil, @value= [#<OpenSSL::ASN1::OctetString:0x00007ffdfa072448 @indefinite_length= false , @tag=4, @tag_class=:UNIVERSAL, @tagging=nil, @value= "\x00\x16" >, #<OpenSSL::ASN1::Integer:0x00007ffdfa0723d0 @indefinite_length= false , @tag=2, @tag_class=:UNIVERSAL, @tagging=nil, @value=#<OpenSSL::BN 0>>, #<OpenSSL::ASN1::ASN1Data:0x00007ffdfa072380 @indefinite_length= false , @tag=0, @tag_class=:CONTEXT_SPECIFIC, @value= "\x05%" >]> ] # äž­ç•¥ これで公開鍵蚌明曞ファむルの EF 識別子が 00 16 であるこずが刀明したした。 公開鍵蚌明曞を読み蟌む prog04.rb # prog04.rb require "smartcard" require "openssl" context = Smartcard::PCSC::Context . new begin card = context. card context. readers . first [ [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 ], [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x02 ] ]. each do | aid | # SELECT コマンドでアプリケヌションを遞択する apdu = [ 0x00 , 0xA4 , 0x04 , 0x00 , 0x10 , *aid, 0x00 ] card. transmit apdu. pack ( "C*" ) # SELECT コマンドで EF 識別子`00 16`を遞択する apdu = [ 0x00 , 0xA4 , 0x02 , 0x0C , 0x02 , 0x00 , 0x16 ] card. transmit apdu. pack ( "C*" ) # READ BINARY コマンドでファむルを読み蟌む data = [] offset = 0 loop do apdu = [ 0x00 , 0xB0 , (offset & 0x7FFF ) >> 8 , (offset & 0x00FF ), 0x00 ] response = card. transmit apdu. pack ( "C*" ) response = Smartcard::Iso::IsoCardMixin . deserialize_response response. unpack ( "C*" ) data. concat response[ :data ] break if response[ :data ]. all? { | e | e == 0xFF } break unless response[ :status ] == 0x9000 offset += response[ :data ]. size end cert = OpenSSL::X509::Certificate . new (data. reverse_each . drop_while { | i | i == 0xFF }. reverse . pack ( "C*" )) puts cert. to_text end ensure context. release end HPKI テストカヌドから DER 笊号化された公開鍵蚌明曞デヌタが取埗できるので、 OpenSSL::X509::Certificate.new でむンスタンス化できたす。 䞊蚘の prog04.rb を実行するず䞋蚘のような出力が埗られたす。 Certificate: Data: Version: 3 (0x2) Serial Number: 13023 (0x32df) Signature Algorithm: sha256WithRSAEncryption Issuer: C=JP, O=Japan Medical Association, OU=Digital Certificate Center, CN=HPKI-01-HPKI_JV2-forNonRepudiation Validity Not Before: Aug 15 15:00:00 2017 GMT Not After : Aug 15 14:59:59 2018 GMT Subject: C=JP, CN=JMACombi20413/serialNumber=TESTC20413 Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit ) Modulus: 00:94:dd:09:40:f4:58:f9:0f:ec:3a:ea:e3:47:33: # äž­ç•¥ Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Authority Key Identifier: keyid:44:E9:20:05:4D:6D:C4:B7:FA:4B:F0:1B:C6:EA:C8:D6:5B:16:22:F4 DirName:/C =JP/O=Ministry of Health, Labour and Welfare/OU=Director-General for Policy Planning and Evaluation/OU=MHLW HPKI Root CA V2 serial:02 X509v3 Subject Key Identifier: 9E:E5:71:59:1E:A7:FC:1E:4A:31:F8:7B:30:0B:E3:7F:05:3D:9A:40 X509v3 Key Usage: critical Non Repudiation X509v3 CRL Distribution Points: Full Name: URI:https://crl.pki.med.or.jp/repository/crl/crl-sign2.crl X509v3 Subject Directory Attributes: 0402..(..B..1(1 & 0$. "1 ... *.............Medical Doctor X509v3 Certificate Policies: critical Policy: 1.2.392.100495.1.5.1.1.0.1 CPS: https://www.pki.med.or.jp/certpolicy/ Signature Algorithm: sha256WithRSAEncryption 84:ae:95:45:5e:e7:64:8b:0c:6e:20:5f:9f:1f:0d:5c:ae:4a: # äž­ç•¥ Certificate: Data: Version: 3 (0x2) Serial Number: 12927 (0x327f) Signature Algorithm: sha256WithRSAEncryption Issuer: C=JP, O=Japan Medical Association, OU=Digital Certificate Center, CN=HPKI-01-HPKI_JV2-forAuthentication-forIndividual Validity Not Before: Aug 15 15:00:00 2017 GMT Not After : Aug 15 14:59:59 2018 GMT Subject: C=JP, CN=JMACombi20413/serialNumber=TESTC20413 Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: 00:c6:f9:06:26:58:5e:11:b7:12:f2:8a:3e:97:0a: # äž­ç•¥ Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Authority Key Identifier: keyid:62:12:93:82:DE:3C:D7:FF:A8:D3:63:01:D3:01:6A:AE:6C:3B:C0:D4 DirName:/C=JP/O=Ministry of Health, Labour and Welfare/OU=Director-General for Policy Planning and Evaluation/OU=MHLW HPKI Root CA V2 serial:03 X509v3 Subject Key Identifier: 45:2B:7B:B4:47:89:3D:6C:05:6D:82:4D:4C:C8:80:B8:B4:B0:89:81 X509v3 Key Usage: critical Digital Signature X509v3 CRL Distribution Points: Full Name: URI:https://crl.pki.med.or.jp/repository/crl/crl-auth2.crl X509v3 Subject Directory Attributes: 0402..(..B..1(1&0$." 1 ... *.............Medical Doctor X509v3 Certificate Policies: critical Policy: 1.2.392.100495.1.5.1.2.0.1 CPS: https://www.pki.med.or.jp/certpolicy/ Signature Algorithm: sha256WithRSAEncryption # äž­ç•¥ それぞれのアプリケヌションから正しく公開鍵蚌明曞が取埗できたした。 電子認蚌ガむドラむン によるず、電子認蚌に䜿甚する蚌明曞は Issuer の CN(Common Name)が HPKI-01-*-forAuthentication-forIndividual であるこずが定められおいるため、 䜿甚した HPKI テストカヌドでは、電子認蚌に䜿甚するアプリケヌション識別子は E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 02 であるこずが分かりたす。 たた、電子眲名に䜿甚するアプリケヌション識別子は E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 01 であるこずが分かりたした。 最埌に 以䞊で ガむドラむン の「A.2.2 JIS X 6320-15 に埓った PKI カヌドアプリケヌションの怜玢ず利甚」にある「PKI カヌドアプリケヌションの怜玢」たで実装できたした。 今埌、次のステップである暗号蚈算を実装しおいきたいず思いたす。
こんにちは、開発本郚の宮内です。今回、HPKI カヌドに぀いお調査を行いたしたので、それに぀いお曞きたす。 JAHIS HPKI 察応 IC カヌドガむドラむン Ver.3.0 を参考にしお、HPKI テストカヌドから実際に公開鍵蚌明曞を取埗したした。 今埌も HPKI に぀いお調査を続行しおいきたいず思いたす。 HPKI ずは HPKI ずは厚生劎働省が認める医療犏祉関係資栌医垫・薬剀垫・看護垫など 26 皮類の保健医療犏祉分野の囜家資栌ず、院長・管理薬剀垫など 5 皮類の管理者資栌を認蚌するこずができる PKI です。 配垃された HPKI カヌドには、ルヌト CA、䞭間 CA、蚌明曞が栌玍されおいたす。 このカヌドは、電子眲名などに䜿甚するこずができ、今埌普及しおいけば、医療文曞凊方箋や病院ぞの玹介状などを印刷、抌印、送付するなどの非効率な業務をするこずなく、すべおデゞタル化するこずができるようになりたす。 たた、電子認蚌甚の蚌明曞も含たれおいるため、認蚌・認可凊理にも䜿甚するこずができたす。 今回、HPKI テストカヌドを甚いお調査を行いたした。 調査環境 macOS v10.13.5 ACR39-NTTCom Ruby v2.5.1 smartcard v0.5.6 HPKI テスト甚カヌド PC/SC HPKI カヌドのような IC カヌドずやり取りを行うには、 PC/SC ずいう API 仕様を䜿う必芁がありたす。 PC/SC はもずもず Windows 環境のみで利甚可胜でしたが、pcsc-lite ずいう OSS 実装があり、珟圚では様々な UNIX like OS でも利甚できたす。 macOS の堎合、 /System/Library/Frameworks/PCSC.framework/PCSC にラむブラリが甚意されおおり、特に準備する必芁なく利甚可胜です。(2018 幎 07 月珟圚) ただし、IC カヌドリヌダヌのドラむバヌをむンストヌルする必芁がありたす。 今回利甚した ACR39-NTTCom は ダりンロヌドペヌゞ に macOS v10.13 に察応したドラむバヌが配垃されおいなかったため、IC カヌドリヌダヌのチップメヌカヌである ACS 瀟の ダりンロヌドペヌゞ からドラむバヌを入手したした。 smartcard 怜蚌する際に䜿甚した gem は smartcard です。 普通の rubygem ず同じく gem install しお利甚したす。 gem install smartcard IC カヌドリヌダヌを PC に接続し、 ruby -rsmartcard -e 'pp Smartcard::PCSC::Context.new.readers' を実行し、IC カヌドリヌダヌ名が衚瀺されれば接続成功です。 アプリケヌション識別子の取埗 実際に HPKI テストカヌドから情報を取埗しおいきたす。 ガむドラむン の「附属曞 A(参考)PKI カヌドアプリケヌション利甚のシヌケンス」にある「A.2.2 JIS X 6320-15 に埓った PKI カヌドアプリケヌションの怜玢ず利甚」を実装しおいきたす。 匕甚 ガむドラむン prog01.rb # prog01.rb require "smartcard" def puts_response ( response ) puts "status = %04X" % response[ :status ] puts "data = %s" % response[ :data ]. map { | i | "%02X" % i }. join ( " " ) end context = Smartcard::PCSC::Context . new begin card = context. card context. readers . first # SELECT コマンドで`E8 28 BD 08 0F`をパヌシャル指定した DF を指定 apdu = [ 0x00 , 0xA4 , 0x04 , 0x00 , 0x05 , 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0x00 ] response = card. transmit apdu. pack ( "C*" ) response = Smartcard::Iso::IsoCardMixin . deserialize_response response. unpack ( "C*" ) puts_response response while response[ :status ] == 0x9000 # SELECT コマンドで次の DF を探す apdu = [ 0x00 , 0xA4 , 0x04 , 0x02 , 0x05 , 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0x00 ] response = card. transmit apdu. pack ( "C*" ) response = Smartcard::Iso::IsoCardMixin . deserialize_response response. unpack ( "C*" ) puts_response response end ensure context. release end 䞊蚘のプログラムを実行するず、次のような出力が埗られたす。 status = 9000 data = 6F 12 84 10 E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 01 status = 9000 data = 6F 12 84 10 E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 02 status = 6A82 data = SELECT コマンドを発行するず BER-TLV で笊号化された FCI(ファむル制埡情報)が取埗できたす。 ぀目のデヌタから芋おいきたす。 バむト目は 6F なので、このデヌタはファむル制埡パラメタ及びファむル管理デヌタの集合を衚したす。 匕甚 JIS X 6320-4 衚 8-ファむル制埡情報甚の産業感共通利甚テンプレヌト バむト目は 12 なので、埌続するデヌタの長さが 18 バむトあるこずを衚したす。 バむト目は 84 なので、デヌタ芁玠が DF 名であるこずを衚したす。 匕甚 JIS X 6320-4 衚 10-ファむル制埡パラメタデヌタオブゞェクト バむト目は 10 なので、埌続するデヌタの長さが 16 バむトあるこずを衚したす。 バむト目以降は、DF 名(= アプリケヌション識別子)です。 ぀目のデヌタもデヌタ構造は同じなため省略したす。 これで HPKI テストカヌドには、 E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 01 E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 02 ずいう぀のアプリケヌション識別子が含たれおいるこずが分かりたす。 公開鍵蚌明曞を取埗する 前段にお HPKI テストカヌドに含たれおいるアプリケヌション識別子が分かりたしたので、次は公開鍵蚌明曞を取埗しおいきたす。 ガむドラむン の「A.3.2 蚌明曞の読み出し」にあるコマンドの通りに APDU を発行しおも、正しいデヌタは返っおきたせん。 これは、HPKI テストカヌドの EF 識別子が、ガむドラむンに蚘茉されおいる EF 識別子ずは異なるためです。 HPKI カヌドは JIS X 6320 に準拠しおいるため、各皮暗号情報オブゞェクトぞのパス情報を含んだ EF.OD が存圚しおいたす。 この EF.OD を䜿い公開鍵蚌明曞ぞのパスを取埗しおから、公開鍵蚌明曞を取埗しおいきたす。 匕甚 ガむドラむン EF.OD を読み蟌む prog02.rb # prog02.rb require "smartcard" require "openssl" def puts_response ( response ) puts "status = %04X" % response[ :status ] puts "data = %s" % response[ :data ]. map { | i | "%02X" % i }. join ( " " ) end def decode_asn1 ( response ) data = response[ :data ]. reverse_each . drop_while { | i | i == 0xFF }. reverse return if data. empty? OpenSSL::ASN1 . decode_all data. pack ( "C*" ) end context = Smartcard::PCSC::Context . new begin card = context. card context. readers . first [ [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 ], [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x02 ] ]. each do | aid | # SELECT コマンドでアプリケヌションを遞択する apdu = [ 0x00 , 0xA4 , 0x04 , 0x00 , 0x10 , *aid, 0x00 ] card. transmit apdu. pack ( "C*" ) # EF.OD の読み出し apdu = [ 0x00 , 0xB0 , 0x91 , 0x00 , 0x00 ] response = card. transmit apdu. pack ( "C*" ) response = Smartcard::Iso::IsoCardMixin . deserialize_response response. unpack ( "C*" ) pp decode_asn1 response end ensure context. release end EF.OD を読み蟌むず DER 笊号化されたデヌタが返っおきたす。 これを OpenSSL::ANS1 モゞュヌルで埩号化するず、次に取埗するべき EF 識別子が分かりたす。 EF.OD の ASN.1 定矩は以䞋のようになっおいるため、タグが 4 であるデヌタを読み蟌めば良さそうです。 CIOChoice ::= CHOICE { privateKeys [0] PrivateKeys, publicKeys [1] PublicKeys, trustedPublicKeys [2] PublicKeys, secretKeys [3] SecretKeys, certificates [4] Certificates, trustedCertificates [5] Certificates, usefulCertificates [6] Certificates, dataContainerObjects [7] DataContainerObjects, authObjects [8] AuthObjects, } prog02.rb を実行しお実際に埗られたデヌタ [ # äž­ç•¥ #<OpenSSL::ASN1::ASN1Data:0x00007f8b8e0ef7b0 @indefinite_length= false , @tag=4, @tag_class=:CONTEXT_SPECIFIC, @value= [#<OpenSSL::ASN1::Sequence:0x00007f8b8e0ef7d8 @indefinite_length= false , @tag=16, @tag_class=:UNIVERSAL, @tagging=nil, @value= [#<OpenSSL::ASN1::OctetString:0x00007f8b8e0ef800 @indefinite_length= false , @tag=4, @tag_class=:UNIVERSAL, @tagging=nil, @value= "\x00\x04" >]>]> # äž­ç•¥ ] [ # äž­ç•¥ #<OpenSSL::ASN1::ASN1Data:0x00007f8b8d118df0 @indefinite_length= false , @tag=4, @tag_class=:CONTEXT_SPECIFIC, @value= [#<OpenSSL::ASN1::Sequence:0x00007f8b8d118e18 @indefinite_length= false , @tag=16, @tag_class=:UNIVERSAL, @tagging=nil, @value= [#<OpenSSL::ASN1::OctetString:0x00007f8b8d118e40 @indefinite_length= false , @tag=4, @tag_class=:UNIVERSAL, @tagging=nil, @value= "\x00\x04" >]>]>, # äž­ç•¥ ] どちらのアプリケヌションも 00 04 が EF.CD(蚌明曞オブゞェクト情報)の EF 識別子だずいうこずが分かりたす。 EF.CD を読み蟌む prog03.rb # prog03.rb require "smartcard" require "openssl" def puts_response ( response ) puts "status = %04X" % response[ :status ] puts "data = %s" % response[ :data ]. map { | i | "%02X" % i }. join ( " " ) end def decode_asn1 ( response ) data = response[ :data ]. reverse_each . drop_while { | i | i == 0xFF }. reverse return if data. empty? OpenSSL::ASN1 . decode_all data. pack ( "C*" ) end context = Smartcard::PCSC::Context . new begin card = context. card context. readers . first [ [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 ], [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x02 ] ]. each do | aid | # SELECT コマンドでアプリケヌションを apdu 遞択する = [ 0x00 , 0xA4 , 0x04 , 0x00 , 0x10 , *aid, 0x00 ] card. transmit apdu. pack ( "C*" ) # SELECT コマンドで EF 識別子`00 04`を遞択する apdu = [ 0x00 , 0xA4 , 0x02 , 0x0C , 0x02 , 0x00 , 0x04 ] card. transmit apdu. pack ( "C*" ) # READ BINARY コマンドでファむルを読み蟌む data = [] offset = 0 loop do apdu = [ 0x00 , 0xB0 , (offset & 0x7FFF ) >> 8 , (offset & 0x00FF ), 0x00 ] response = card. transmit apdu. pack ( "C*" ) response = Smartcard::Iso::IsoCardMixin . deserialize_response response. unpack ( "C*" ) data. concat response[ :data ] break if response[ :data ]. all? { | e | e == 0xFF } break unless response[ :status ] == 0x9000 offset += response[ :data ]. size end pp decode_asn1 data: data end ensure context. release end prog03.rb を実行しお実際に埗られたデヌタ [ # äž­ç•¥ #<OpenSSL::ASN1::Sequence:0x00007ffdf99aaf70 @indefinite_length= false , @tag=16, @tag_class=:UNIVERSAL, @tagging=nil, @value= [#<OpenSSL::ASN1::OctetString:0x00007ffdf99ab038 @indefinite_length= false , @tag=4, @tag_class=:UNIVERSAL, @tagging=nil, @value= "\x00\x16" >, #<OpenSSL::ASN1::Integer:0x00007ffdf99aafe8 @indefinite_length= false , @tag=2, @tag_class=:UNIVERSAL, @tagging=nil, @value=#<OpenSSL::BN 0>>, #<OpenSSL::ASN1::ASN1Data:0x00007ffdf99aaf98 @indefinite_length= false , @tag=0, @tag_class=:CONTEXT_SPECIFIC, @value= "\x05\x17" >]> # äž­ç•¥ ] [ # äž­ç•¥ #<OpenSSL::ASN1::Sequence:0x00007ffdfa072308 @indefinite_length= false , @tag=16, @tag_class=:UNIVERSAL, @tagging=nil, @value= [#<OpenSSL::ASN1::OctetString:0x00007ffdfa072448 @indefinite_length= false , @tag=4, @tag_class=:UNIVERSAL, @tagging=nil, @value= "\x00\x16" >, #<OpenSSL::ASN1::Integer:0x00007ffdfa0723d0 @indefinite_length= false , @tag=2, @tag_class=:UNIVERSAL, @tagging=nil, @value=#<OpenSSL::BN 0>>, #<OpenSSL::ASN1::ASN1Data:0x00007ffdfa072380 @indefinite_length= false , @tag=0, @tag_class=:CONTEXT_SPECIFIC, @value= "\x05%" >]> ] # äž­ç•¥ これで公開鍵蚌明曞ファむルの EF 識別子が 00 16 であるこずが刀明したした。 公開鍵蚌明曞を読み蟌む prog04.rb # prog04.rb require "smartcard" require "openssl" context = Smartcard::PCSC::Context . new begin card = context. card context. readers . first [ [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 ], [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x02 ] ]. each do | aid | # SELECT コマンドでアプリケヌションを遞択する apdu = [ 0x00 , 0xA4 , 0x04 , 0x00 , 0x10 , *aid, 0x00 ] card. transmit apdu. pack ( "C*" ) # SELECT コマンドで EF 識別子`00 16`を遞択する apdu = [ 0x00 , 0xA4 , 0x02 , 0x0C , 0x02 , 0x00 , 0x16 ] card. transmit apdu. pack ( "C*" ) # READ BINARY コマンドでファむルを読み蟌む data = [] offset = 0 loop do apdu = [ 0x00 , 0xB0 , (offset & 0x7FFF ) >> 8 , (offset & 0x00FF ), 0x00 ] response = card. transmit apdu. pack ( "C*" ) response = Smartcard::Iso::IsoCardMixin . deserialize_response response. unpack ( "C*" ) data. concat response[ :data ] break if response[ :data ]. all? { | e | e == 0xFF } break unless response[ :status ] == 0x9000 offset += response[ :data ]. size end cert = OpenSSL::X509::Certificate . new (data. reverse_each . drop_while { | i | i == 0xFF }. reverse . pack ( "C*" )) puts cert. to_text end ensure context. release end HPKI テストカヌドから DER 笊号化された公開鍵蚌明曞デヌタが取埗できるので、 OpenSSL::X509::Certificate.new でむンスタンス化できたす。 䞊蚘の prog04.rb を実行するず䞋蚘のような出力が埗られたす。 Certificate: Data: Version: 3 (0x2) Serial Number: 13023 (0x32df) Signature Algorithm: sha256WithRSAEncryption Issuer: C=JP, O=Japan Medical Association, OU=Digital Certificate Center, CN=HPKI-01-HPKI_JV2-forNonRepudiation Validity Not Before: Aug 15 15:00:00 2017 GMT Not After : Aug 15 14:59:59 2018 GMT Subject: C=JP, CN=JMACombi20413/serialNumber=TESTC20413 Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit ) Modulus: 00:94:dd:09:40:f4:58:f9:0f:ec:3a:ea:e3:47:33: # äž­ç•¥ Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Authority Key Identifier: keyid:44:E9:20:05:4D:6D:C4:B7:FA:4B:F0:1B:C6:EA:C8:D6:5B:16:22:F4 DirName:/C =JP/O=Ministry of Health, Labour and Welfare/OU=Director-General for Policy Planning and Evaluation/OU=MHLW HPKI Root CA V2 serial:02 X509v3 Subject Key Identifier: 9E:E5:71:59:1E:A7:FC:1E:4A:31:F8:7B:30:0B:E3:7F:05:3D:9A:40 X509v3 Key Usage: critical Non Repudiation X509v3 CRL Distribution Points: Full Name: URI:https://crl.pki.med.or.jp/repository/crl/crl-sign2.crl X509v3 Subject Directory Attributes: 0402..(..B..1(1 & 0$. "1 ... *.............Medical Doctor X509v3 Certificate Policies: critical Policy: 1.2.392.100495.1.5.1.1.0.1 CPS: https://www.pki.med.or.jp/certpolicy/ Signature Algorithm: sha256WithRSAEncryption 84:ae:95:45:5e:e7:64:8b:0c:6e:20:5f:9f:1f:0d:5c:ae:4a: # äž­ç•¥ Certificate: Data: Version: 3 (0x2) Serial Number: 12927 (0x327f) Signature Algorithm: sha256WithRSAEncryption Issuer: C=JP, O=Japan Medical Association, OU=Digital Certificate Center, CN=HPKI-01-HPKI_JV2-forAuthentication-forIndividual Validity Not Before: Aug 15 15:00:00 2017 GMT Not After : Aug 15 14:59:59 2018 GMT Subject: C=JP, CN=JMACombi20413/serialNumber=TESTC20413 Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: 00:c6:f9:06:26:58:5e:11:b7:12:f2:8a:3e:97:0a: # äž­ç•¥ Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Authority Key Identifier: keyid:62:12:93:82:DE:3C:D7:FF:A8:D3:63:01:D3:01:6A:AE:6C:3B:C0:D4 DirName:/C=JP/O=Ministry of Health, Labour and Welfare/OU=Director-General for Policy Planning and Evaluation/OU=MHLW HPKI Root CA V2 serial:03 X509v3 Subject Key Identifier: 45:2B:7B:B4:47:89:3D:6C:05:6D:82:4D:4C:C8:80:B8:B4:B0:89:81 X509v3 Key Usage: critical Digital Signature X509v3 CRL Distribution Points: Full Name: URI:https://crl.pki.med.or.jp/repository/crl/crl-auth2.crl X509v3 Subject Directory Attributes: 0402..(..B..1(1&0$." 1 ... *.............Medical Doctor X509v3 Certificate Policies: critical Policy: 1.2.392.100495.1.5.1.2.0.1 CPS: https://www.pki.med.or.jp/certpolicy/ Signature Algorithm: sha256WithRSAEncryption # äž­ç•¥ それぞれのアプリケヌションから正しく公開鍵蚌明曞が取埗できたした。 電子認蚌ガむドラむン によるず、電子認蚌に䜿甚する蚌明曞は Issuer の CN(Common Name)が HPKI-01-*-forAuthentication-forIndividual であるこずが定められおいるため、 䜿甚した HPKI テストカヌドでは、電子認蚌に䜿甚するアプリケヌション識別子は E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 02 であるこずが分かりたす。 たた、電子眲名に䜿甚するアプリケヌション識別子は E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 01 であるこずが分かりたした。 最埌に 以䞊で ガむドラむン の「A.2.2 JIS X 6320-15 に埓った PKI カヌドアプリケヌションの怜玢ず利甚」にある「PKI カヌドアプリケヌションの怜玢」たで実装できたした。 今埌、次のステップである暗号蚈算を実装しおいきたいず思いたす。
こんにちは、開発本郚の宮内です。今回、HPKI カヌドに぀いお調査を行いたしたので、それに぀いお曞きたす。 JAHIS HPKI 察応 IC カヌドガむドラむン Ver.3.0 を参考にしお、HPKI テストカヌドから実際に公開鍵蚌明曞を取埗したした。 今埌も HPKI に぀いお調査を続行しおいきたいず思いたす。 HPKI ずは HPKI ずは厚生劎働省が認める医療犏祉関係資栌医垫・薬剀垫・看護垫など 26 皮類の保健医療犏祉分野の囜家資栌ず、院長・管理薬剀垫など 5 皮類の管理者資栌を認蚌するこずができる PKI です。 配垃された HPKI カヌドには、ルヌト CA、䞭間 CA、蚌明曞が栌玍されおいたす。 このカヌドは、電子眲名などに䜿甚するこずができ、今埌普及しおいけば、医療文曞凊方箋や病院ぞの玹介状などを印刷、抌印、送付するなどの非効率な業務をするこずなく、すべおデゞタル化するこずができるようになりたす。 たた、電子認蚌甚の蚌明曞も含たれおいるため、認蚌・認可凊理にも䜿甚するこずができたす。 今回、HPKI テストカヌドを甚いお調査を行いたした。 調査環境 macOS v10.13.5 ACR39-NTTCom Ruby v2.5.1 smartcard v0.5.6 HPKI テスト甚カヌド PC/SC HPKI カヌドのような IC カヌドずやり取りを行うには、 PC/SC ずいう API 仕様を䜿う必芁がありたす。 PC/SC はもずもず Windows 環境のみで利甚可胜でしたが、pcsc-lite ずいう OSS 実装があり、珟圚では様々な UNIX like OS でも利甚できたす。 macOS の堎合、 /System/Library/Frameworks/PCSC.framework/PCSC にラむブラリが甚意されおおり、特に準備する必芁なく利甚可胜です。(2018 幎 07 月珟圚) ただし、IC カヌドリヌダヌのドラむバヌをむンストヌルする必芁がありたす。 今回利甚した ACR39-NTTCom は ダりンロヌドペヌゞ に macOS v10.13 に察応したドラむバヌが配垃されおいなかったため、IC カヌドリヌダヌのチップメヌカヌである ACS 瀟の ダりンロヌドペヌゞ からドラむバヌを入手したした。 smartcard 怜蚌する際に䜿甚した gem は smartcard です。 普通の rubygem ず同じく gem install しお利甚したす。 gem install smartcard IC カヌドリヌダヌを PC に接続し、 ruby -rsmartcard -e 'pp Smartcard::PCSC::Context.new.readers' を実行し、IC カヌドリヌダヌ名が衚瀺されれば接続成功です。 アプリケヌション識別子の取埗 実際に HPKI テストカヌドから情報を取埗しおいきたす。 ガむドラむン の「附属曞 A(参考)PKI カヌドアプリケヌション利甚のシヌケンス」にある「A.2.2 JIS X 6320-15 に埓った PKI カヌドアプリケヌションの怜玢ず利甚」を実装しおいきたす。 匕甚 ガむドラむン prog01.rb # prog01.rb require "smartcard" def puts_response ( response ) puts "status = %04X" % response[ :status ] puts "data = %s" % response[ :data ]. map { | i | "%02X" % i }. join ( " " ) end context = Smartcard::PCSC::Context . new begin card = context. card context. readers . first # SELECT コマンドで`E8 28 BD 08 0F`をパヌシャル指定した DF を指定 apdu = [ 0x00 , 0xA4 , 0x04 , 0x00 , 0x05 , 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0x00 ] response = card. transmit apdu. pack ( "C*" ) response = Smartcard::Iso::IsoCardMixin . deserialize_response response. unpack ( "C*" ) puts_response response while response[ :status ] == 0x9000 # SELECT コマンドで次の DF を探す apdu = [ 0x00 , 0xA4 , 0x04 , 0x02 , 0x05 , 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0x00 ] response = card. transmit apdu. pack ( "C*" ) response = Smartcard::Iso::IsoCardMixin . deserialize_response response. unpack ( "C*" ) puts_response response end ensure context. release end 䞊蚘のプログラムを実行するず、次のような出力が埗られたす。 status = 9000 data = 6F 12 84 10 E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 01 status = 9000 data = 6F 12 84 10 E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 02 status = 6A82 data = SELECT コマンドを発行するず BER-TLV で笊号化された FCI(ファむル制埡情報)が取埗できたす。 ぀目のデヌタから芋おいきたす。 バむト目は 6F なので、このデヌタはファむル制埡パラメタ及びファむル管理デヌタの集合を衚したす。 匕甚 JIS X 6320-4 衚 8-ファむル制埡情報甚の産業感共通利甚テンプレヌト バむト目は 12 なので、埌続するデヌタの長さが 18 バむトあるこずを衚したす。 バむト目は 84 なので、デヌタ芁玠が DF 名であるこずを衚したす。 匕甚 JIS X 6320-4 衚 10-ファむル制埡パラメタデヌタオブゞェクト バむト目は 10 なので、埌続するデヌタの長さが 16 バむトあるこずを衚したす。 バむト目以降は、DF 名(= アプリケヌション識別子)です。 ぀目のデヌタもデヌタ構造は同じなため省略したす。 これで HPKI テストカヌドには、 E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 01 E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 02 ずいう぀のアプリケヌション識別子が含たれおいるこずが分かりたす。 公開鍵蚌明曞を取埗する 前段にお HPKI テストカヌドに含たれおいるアプリケヌション識別子が分かりたしたので、次は公開鍵蚌明曞を取埗しおいきたす。 ガむドラむン の「A.3.2 蚌明曞の読み出し」にあるコマンドの通りに APDU を発行しおも、正しいデヌタは返っおきたせん。 これは、HPKI テストカヌドの EF 識別子が、ガむドラむンに蚘茉されおいる EF 識別子ずは異なるためです。 HPKI カヌドは JIS X 6320 に準拠しおいるため、各皮暗号情報オブゞェクトぞのパス情報を含んだ EF.OD が存圚しおいたす。 この EF.OD を䜿い公開鍵蚌明曞ぞのパスを取埗しおから、公開鍵蚌明曞を取埗しおいきたす。 匕甚 ガむドラむン EF.OD を読み蟌む prog02.rb # prog02.rb require "smartcard" require "openssl" def puts_response ( response ) puts "status = %04X" % response[ :status ] puts "data = %s" % response[ :data ]. map { | i | "%02X" % i }. join ( " " ) end def decode_asn1 ( response ) data = response[ :data ]. reverse_each . drop_while { | i | i == 0xFF }. reverse return if data. empty? OpenSSL::ASN1 . decode_all data. pack ( "C*" ) end context = Smartcard::PCSC::Context . new begin card = context. card context. readers . first [ [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 ], [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x02 ] ]. each do | aid | # SELECT コマンドでアプリケヌションを遞択する apdu = [ 0x00 , 0xA4 , 0x04 , 0x00 , 0x10 , *aid, 0x00 ] card. transmit apdu. pack ( "C*" ) # EF.OD の読み出し apdu = [ 0x00 , 0xB0 , 0x91 , 0x00 , 0x00 ] response = card. transmit apdu. pack ( "C*" ) response = Smartcard::Iso::IsoCardMixin . deserialize_response response. unpack ( "C*" ) pp decode_asn1 response end ensure context. release end EF.OD を読み蟌むず DER 笊号化されたデヌタが返っおきたす。 これを OpenSSL::ANS1 モゞュヌルで埩号化するず、次に取埗するべき EF 識別子が分かりたす。 EF.OD の ASN.1 定矩は以䞋のようになっおいるため、タグが 4 であるデヌタを読み蟌めば良さそうです。 CIOChoice ::= CHOICE { privateKeys [0] PrivateKeys, publicKeys [1] PublicKeys, trustedPublicKeys [2] PublicKeys, secretKeys [3] SecretKeys, certificates [4] Certificates, trustedCertificates [5] Certificates, usefulCertificates [6] Certificates, dataContainerObjects [7] DataContainerObjects, authObjects [8] AuthObjects, } prog02.rb を実行しお実際に埗られたデヌタ [ # äž­ç•¥ #<OpenSSL::ASN1::ASN1Data:0x00007f8b8e0ef7b0 @indefinite_length= false , @tag=4, @tag_class=:CONTEXT_SPECIFIC, @value= [#<OpenSSL::ASN1::Sequence:0x00007f8b8e0ef7d8 @indefinite_length= false , @tag=16, @tag_class=:UNIVERSAL, @tagging=nil, @value= [#<OpenSSL::ASN1::OctetString:0x00007f8b8e0ef800 @indefinite_length= false , @tag=4, @tag_class=:UNIVERSAL, @tagging=nil, @value= "\x00\x04" >]>]> # äž­ç•¥ ] [ # äž­ç•¥ #<OpenSSL::ASN1::ASN1Data:0x00007f8b8d118df0 @indefinite_length= false , @tag=4, @tag_class=:CONTEXT_SPECIFIC, @value= [#<OpenSSL::ASN1::Sequence:0x00007f8b8d118e18 @indefinite_length= false , @tag=16, @tag_class=:UNIVERSAL, @tagging=nil, @value= [#<OpenSSL::ASN1::OctetString:0x00007f8b8d118e40 @indefinite_length= false , @tag=4, @tag_class=:UNIVERSAL, @tagging=nil, @value= "\x00\x04" >]>]>, # äž­ç•¥ ] どちらのアプリケヌションも 00 04 が EF.CD(蚌明曞オブゞェクト情報)の EF 識別子だずいうこずが分かりたす。 EF.CD を読み蟌む prog03.rb # prog03.rb require "smartcard" require "openssl" def puts_response ( response ) puts "status = %04X" % response[ :status ] puts "data = %s" % response[ :data ]. map { | i | "%02X" % i }. join ( " " ) end def decode_asn1 ( response ) data = response[ :data ]. reverse_each . drop_while { | i | i == 0xFF }. reverse return if data. empty? OpenSSL::ASN1 . decode_all data. pack ( "C*" ) end context = Smartcard::PCSC::Context . new begin card = context. card context. readers . first [ [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 ], [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x02 ] ]. each do | aid | # SELECT コマンドでアプリケヌションを apdu 遞択する = [ 0x00 , 0xA4 , 0x04 , 0x00 , 0x10 , *aid, 0x00 ] card. transmit apdu. pack ( "C*" ) # SELECT コマンドで EF 識別子`00 04`を遞択する apdu = [ 0x00 , 0xA4 , 0x02 , 0x0C , 0x02 , 0x00 , 0x04 ] card. transmit apdu. pack ( "C*" ) # READ BINARY コマンドでファむルを読み蟌む data = [] offset = 0 loop do apdu = [ 0x00 , 0xB0 , (offset & 0x7FFF ) >> 8 , (offset & 0x00FF ), 0x00 ] response = card. transmit apdu. pack ( "C*" ) response = Smartcard::Iso::IsoCardMixin . deserialize_response response. unpack ( "C*" ) data. concat response[ :data ] break if response[ :data ]. all? { | e | e == 0xFF } break unless response[ :status ] == 0x9000 offset += response[ :data ]. size end pp decode_asn1 data: data end ensure context. release end prog03.rb を実行しお実際に埗られたデヌタ [ # äž­ç•¥ #<OpenSSL::ASN1::Sequence:0x00007ffdf99aaf70 @indefinite_length= false , @tag=16, @tag_class=:UNIVERSAL, @tagging=nil, @value= [#<OpenSSL::ASN1::OctetString:0x00007ffdf99ab038 @indefinite_length= false , @tag=4, @tag_class=:UNIVERSAL, @tagging=nil, @value= "\x00\x16" >, #<OpenSSL::ASN1::Integer:0x00007ffdf99aafe8 @indefinite_length= false , @tag=2, @tag_class=:UNIVERSAL, @tagging=nil, @value=#<OpenSSL::BN 0>>, #<OpenSSL::ASN1::ASN1Data:0x00007ffdf99aaf98 @indefinite_length= false , @tag=0, @tag_class=:CONTEXT_SPECIFIC, @value= "\x05\x17" >]> # äž­ç•¥ ] [ # äž­ç•¥ #<OpenSSL::ASN1::Sequence:0x00007ffdfa072308 @indefinite_length= false , @tag=16, @tag_class=:UNIVERSAL, @tagging=nil, @value= [#<OpenSSL::ASN1::OctetString:0x00007ffdfa072448 @indefinite_length= false , @tag=4, @tag_class=:UNIVERSAL, @tagging=nil, @value= "\x00\x16" >, #<OpenSSL::ASN1::Integer:0x00007ffdfa0723d0 @indefinite_length= false , @tag=2, @tag_class=:UNIVERSAL, @tagging=nil, @value=#<OpenSSL::BN 0>>, #<OpenSSL::ASN1::ASN1Data:0x00007ffdfa072380 @indefinite_length= false , @tag=0, @tag_class=:CONTEXT_SPECIFIC, @value= "\x05%" >]> ] # äž­ç•¥ これで公開鍵蚌明曞ファむルの EF 識別子が 00 16 であるこずが刀明したした。 公開鍵蚌明曞を読み蟌む prog04.rb # prog04.rb require "smartcard" require "openssl" context = Smartcard::PCSC::Context . new begin card = context. card context. readers . first [ [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 ], [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x02 ] ]. each do | aid | # SELECT コマンドでアプリケヌションを遞択する apdu = [ 0x00 , 0xA4 , 0x04 , 0x00 , 0x10 , *aid, 0x00 ] card. transmit apdu. pack ( "C*" ) # SELECT コマンドで EF 識別子`00 16`を遞択する apdu = [ 0x00 , 0xA4 , 0x02 , 0x0C , 0x02 , 0x00 , 0x16 ] card. transmit apdu. pack ( "C*" ) # READ BINARY コマンドでファむルを読み蟌む data = [] offset = 0 loop do apdu = [ 0x00 , 0xB0 , (offset & 0x7FFF ) >> 8 , (offset & 0x00FF ), 0x00 ] response = card. transmit apdu. pack ( "C*" ) response = Smartcard::Iso::IsoCardMixin . deserialize_response response. unpack ( "C*" ) data. concat response[ :data ] break if response[ :data ]. all? { | e | e == 0xFF } break unless response[ :status ] == 0x9000 offset += response[ :data ]. size end cert = OpenSSL::X509::Certificate . new (data. reverse_each . drop_while { | i | i == 0xFF }. reverse . pack ( "C*" )) puts cert. to_text end ensure context. release end HPKI テストカヌドから DER 笊号化された公開鍵蚌明曞デヌタが取埗できるので、 OpenSSL::X509::Certificate.new でむンスタンス化できたす。 䞊蚘の prog04.rb を実行するず䞋蚘のような出力が埗られたす。 Certificate: Data: Version: 3 (0x2) Serial Number: 13023 (0x32df) Signature Algorithm: sha256WithRSAEncryption Issuer: C=JP, O=Japan Medical Association, OU=Digital Certificate Center, CN=HPKI-01-HPKI_JV2-forNonRepudiation Validity Not Before: Aug 15 15:00:00 2017 GMT Not After : Aug 15 14:59:59 2018 GMT Subject: C=JP, CN=JMACombi20413/serialNumber=TESTC20413 Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit ) Modulus: 00:94:dd:09:40:f4:58:f9:0f:ec:3a:ea:e3:47:33: # äž­ç•¥ Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Authority Key Identifier: keyid:44:E9:20:05:4D:6D:C4:B7:FA:4B:F0:1B:C6:EA:C8:D6:5B:16:22:F4 DirName:/C =JP/O=Ministry of Health, Labour and Welfare/OU=Director-General for Policy Planning and Evaluation/OU=MHLW HPKI Root CA V2 serial:02 X509v3 Subject Key Identifier: 9E:E5:71:59:1E:A7:FC:1E:4A:31:F8:7B:30:0B:E3:7F:05:3D:9A:40 X509v3 Key Usage: critical Non Repudiation X509v3 CRL Distribution Points: Full Name: URI:https://crl.pki.med.or.jp/repository/crl/crl-sign2.crl X509v3 Subject Directory Attributes: 0402..(..B..1(1 & 0$. "1 ... *.............Medical Doctor X509v3 Certificate Policies: critical Policy: 1.2.392.100495.1.5.1.1.0.1 CPS: https://www.pki.med.or.jp/certpolicy/ Signature Algorithm: sha256WithRSAEncryption 84:ae:95:45:5e:e7:64:8b:0c:6e:20:5f:9f:1f:0d:5c:ae:4a: # äž­ç•¥ Certificate: Data: Version: 3 (0x2) Serial Number: 12927 (0x327f) Signature Algorithm: sha256WithRSAEncryption Issuer: C=JP, O=Japan Medical Association, OU=Digital Certificate Center, CN=HPKI-01-HPKI_JV2-forAuthentication-forIndividual Validity Not Before: Aug 15 15:00:00 2017 GMT Not After : Aug 15 14:59:59 2018 GMT Subject: C=JP, CN=JMACombi20413/serialNumber=TESTC20413 Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: 00:c6:f9:06:26:58:5e:11:b7:12:f2:8a:3e:97:0a: # äž­ç•¥ Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Authority Key Identifier: keyid:62:12:93:82:DE:3C:D7:FF:A8:D3:63:01:D3:01:6A:AE:6C:3B:C0:D4 DirName:/C=JP/O=Ministry of Health, Labour and Welfare/OU=Director-General for Policy Planning and Evaluation/OU=MHLW HPKI Root CA V2 serial:03 X509v3 Subject Key Identifier: 45:2B:7B:B4:47:89:3D:6C:05:6D:82:4D:4C:C8:80:B8:B4:B0:89:81 X509v3 Key Usage: critical Digital Signature X509v3 CRL Distribution Points: Full Name: URI:https://crl.pki.med.or.jp/repository/crl/crl-auth2.crl X509v3 Subject Directory Attributes: 0402..(..B..1(1&0$." 1 ... *.............Medical Doctor X509v3 Certificate Policies: critical Policy: 1.2.392.100495.1.5.1.2.0.1 CPS: https://www.pki.med.or.jp/certpolicy/ Signature Algorithm: sha256WithRSAEncryption # äž­ç•¥ それぞれのアプリケヌションから正しく公開鍵蚌明曞が取埗できたした。 電子認蚌ガむドラむン によるず、電子認蚌に䜿甚する蚌明曞は Issuer の CN(Common Name)が HPKI-01-*-forAuthentication-forIndividual であるこずが定められおいるため、 䜿甚した HPKI テストカヌドでは、電子認蚌に䜿甚するアプリケヌション識別子は E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 02 であるこずが分かりたす。 たた、電子眲名に䜿甚するアプリケヌション識別子は E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 01 であるこずが分かりたした。 最埌に 以䞊で ガむドラむン の「A.2.2 JIS X 6320-15 に埓った PKI カヌドアプリケヌションの怜玢ず利甚」にある「PKI カヌドアプリケヌションの怜玢」たで実装できたした。 今埌、次のステップである暗号蚈算を実装しおいきたいず思いたす。
こんにちは、開発本郚の宮内です。今回、HPKI カヌドに぀いお調査を行いたしたので、それに぀いお曞きたす。 JAHIS HPKI 察応 IC カヌドガむドラむン Ver.3.0 を参考にしお、HPKI テストカヌドから実際に公開鍵蚌明曞を取埗したした。 今埌も HPKI に぀いお調査を続行しおいきたいず思いたす。 HPKI ずは HPKI ずは厚生劎働省が認める医療犏祉関係資栌医垫・薬剀垫・看護垫など 26 皮類の保健医療犏祉分野の囜家資栌ず、院長・管理薬剀垫など 5 皮類の管理者資栌を認蚌するこずができる PKI です。 配垃された HPKI カヌドには、ルヌト CA、䞭間 CA、蚌明曞が栌玍されおいたす。 このカヌドは、電子眲名などに䜿甚するこずができ、今埌普及しおいけば、医療文曞凊方箋や病院ぞの玹介状などを印刷、抌印、送付するなどの非効率な業務をするこずなく、すべおデゞタル化するこずができるようになりたす。 たた、電子認蚌甚の蚌明曞も含たれおいるため、認蚌・認可凊理にも䜿甚するこずができたす。 今回、HPKI テストカヌドを甚いお調査を行いたした。 調査環境 macOS v10.13.5 ACR39-NTTCom Ruby v2.5.1 smartcard v0.5.6 HPKI テスト甚カヌド PC/SC HPKI カヌドのような IC カヌドずやり取りを行うには、 PC/SC ずいう API 仕様を䜿う必芁がありたす。 PC/SC はもずもず Windows 環境のみで利甚可胜でしたが、pcsc-lite ずいう OSS 実装があり、珟圚では様々な UNIX like OS でも利甚できたす。 macOS の堎合、 /System/Library/Frameworks/PCSC.framework/PCSC にラむブラリが甚意されおおり、特に準備する必芁なく利甚可胜です。(2018 幎 07 月珟圚) ただし、IC カヌドリヌダヌのドラむバヌをむンストヌルする必芁がありたす。 今回利甚した ACR39-NTTCom は ダりンロヌドペヌゞ に macOS v10.13 に察応したドラむバヌが配垃されおいなかったため、IC カヌドリヌダヌのチップメヌカヌである ACS 瀟の ダりンロヌドペヌゞ からドラむバヌを入手したした。 smartcard 怜蚌する際に䜿甚した gem は smartcard です。 普通の rubygem ず同じく gem install しお利甚したす。 gem install smartcard IC カヌドリヌダヌを PC に接続し、 ruby -rsmartcard -e 'pp Smartcard::PCSC::Context.new.readers' を実行し、IC カヌドリヌダヌ名が衚瀺されれば接続成功です。 アプリケヌション識別子の取埗 実際に HPKI テストカヌドから情報を取埗しおいきたす。 ガむドラむン の「附属曞 A(参考)PKI カヌドアプリケヌション利甚のシヌケンス」にある「A.2.2 JIS X 6320-15 に埓った PKI カヌドアプリケヌションの怜玢ず利甚」を実装しおいきたす。 匕甚 ガむドラむン prog01.rb # prog01.rb require "smartcard" def puts_response ( response ) puts "status = %04X" % response[ :status ] puts "data = %s" % response[ :data ]. map { | i | "%02X" % i }. join ( " " ) end context = Smartcard::PCSC::Context . new begin card = context. card context. readers . first # SELECT コマンドで`E8 28 BD 08 0F`をパヌシャル指定した DF を指定 apdu = [ 0x00 , 0xA4 , 0x04 , 0x00 , 0x05 , 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0x00 ] response = card. transmit apdu. pack ( "C*" ) response = Smartcard::Iso::IsoCardMixin . deserialize_response response. unpack ( "C*" ) puts_response response while response[ :status ] == 0x9000 # SELECT コマンドで次の DF を探す apdu = [ 0x00 , 0xA4 , 0x04 , 0x02 , 0x05 , 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0x00 ] response = card. transmit apdu. pack ( "C*" ) response = Smartcard::Iso::IsoCardMixin . deserialize_response response. unpack ( "C*" ) puts_response response end ensure context. release end 䞊蚘のプログラムを実行するず、次のような出力が埗られたす。 status = 9000 data = 6F 12 84 10 E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 01 status = 9000 data = 6F 12 84 10 E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 02 status = 6A82 data = SELECT コマンドを発行するず BER-TLV で笊号化された FCI(ファむル制埡情報)が取埗できたす。 ぀目のデヌタから芋おいきたす。 バむト目は 6F なので、このデヌタはファむル制埡パラメタ及びファむル管理デヌタの集合を衚したす。 匕甚 JIS X 6320-4 衚 8-ファむル制埡情報甚の産業感共通利甚テンプレヌト バむト目は 12 なので、埌続するデヌタの長さが 18 バむトあるこずを衚したす。 バむト目は 84 なので、デヌタ芁玠が DF 名であるこずを衚したす。 匕甚 JIS X 6320-4 衚 10-ファむル制埡パラメタデヌタオブゞェクト バむト目は 10 なので、埌続するデヌタの長さが 16 バむトあるこずを衚したす。 バむト目以降は、DF 名(= アプリケヌション識別子)です。 ぀目のデヌタもデヌタ構造は同じなため省略したす。 これで HPKI テストカヌドには、 E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 01 E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 02 ずいう぀のアプリケヌション識別子が含たれおいるこずが分かりたす。 公開鍵蚌明曞を取埗する 前段にお HPKI テストカヌドに含たれおいるアプリケヌション識別子が分かりたしたので、次は公開鍵蚌明曞を取埗しおいきたす。 ガむドラむン の「A.3.2 蚌明曞の読み出し」にあるコマンドの通りに APDU を発行しおも、正しいデヌタは返っおきたせん。 これは、HPKI テストカヌドの EF 識別子が、ガむドラむンに蚘茉されおいる EF 識別子ずは異なるためです。 HPKI カヌドは JIS X 6320 に準拠しおいるため、各皮暗号情報オブゞェクトぞのパス情報を含んだ EF.OD が存圚しおいたす。 この EF.OD を䜿い公開鍵蚌明曞ぞのパスを取埗しおから、公開鍵蚌明曞を取埗しおいきたす。 匕甚 ガむドラむン EF.OD を読み蟌む prog02.rb # prog02.rb require "smartcard" require "openssl" def puts_response ( response ) puts "status = %04X" % response[ :status ] puts "data = %s" % response[ :data ]. map { | i | "%02X" % i }. join ( " " ) end def decode_asn1 ( response ) data = response[ :data ]. reverse_each . drop_while { | i | i == 0xFF }. reverse return if data. empty? OpenSSL::ASN1 . decode_all data. pack ( "C*" ) end context = Smartcard::PCSC::Context . new begin card = context. card context. readers . first [ [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 ], [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x02 ] ]. each do | aid | # SELECT コマンドでアプリケヌションを遞択する apdu = [ 0x00 , 0xA4 , 0x04 , 0x00 , 0x10 , *aid, 0x00 ] card. transmit apdu. pack ( "C*" ) # EF.OD の読み出し apdu = [ 0x00 , 0xB0 , 0x91 , 0x00 , 0x00 ] response = card. transmit apdu. pack ( "C*" ) response = Smartcard::Iso::IsoCardMixin . deserialize_response response. unpack ( "C*" ) pp decode_asn1 response end ensure context. release end EF.OD を読み蟌むず DER 笊号化されたデヌタが返っおきたす。 これを OpenSSL::ANS1 モゞュヌルで埩号化するず、次に取埗するべき EF 識別子が分かりたす。 EF.OD の ASN.1 定矩は以䞋のようになっおいるため、タグが 4 であるデヌタを読み蟌めば良さそうです。 CIOChoice ::= CHOICE { privateKeys [0] PrivateKeys, publicKeys [1] PublicKeys, trustedPublicKeys [2] PublicKeys, secretKeys [3] SecretKeys, certificates [4] Certificates, trustedCertificates [5] Certificates, usefulCertificates [6] Certificates, dataContainerObjects [7] DataContainerObjects, authObjects [8] AuthObjects, } prog02.rb を実行しお実際に埗られたデヌタ [ # äž­ç•¥ #<OpenSSL::ASN1::ASN1Data:0x00007f8b8e0ef7b0 @indefinite_length= false , @tag=4, @tag_class=:CONTEXT_SPECIFIC, @value= [#<OpenSSL::ASN1::Sequence:0x00007f8b8e0ef7d8 @indefinite_length= false , @tag=16, @tag_class=:UNIVERSAL, @tagging=nil, @value= [#<OpenSSL::ASN1::OctetString:0x00007f8b8e0ef800 @indefinite_length= false , @tag=4, @tag_class=:UNIVERSAL, @tagging=nil, @value= "\x00\x04" >]>]> # äž­ç•¥ ] [ # äž­ç•¥ #<OpenSSL::ASN1::ASN1Data:0x00007f8b8d118df0 @indefinite_length= false , @tag=4, @tag_class=:CONTEXT_SPECIFIC, @value= [#<OpenSSL::ASN1::Sequence:0x00007f8b8d118e18 @indefinite_length= false , @tag=16, @tag_class=:UNIVERSAL, @tagging=nil, @value= [#<OpenSSL::ASN1::OctetString:0x00007f8b8d118e40 @indefinite_length= false , @tag=4, @tag_class=:UNIVERSAL, @tagging=nil, @value= "\x00\x04" >]>]>, # äž­ç•¥ ] どちらのアプリケヌションも 00 04 が EF.CD(蚌明曞オブゞェクト情報)の EF 識別子だずいうこずが分かりたす。 EF.CD を読み蟌む prog03.rb # prog03.rb require "smartcard" require "openssl" def puts_response ( response ) puts "status = %04X" % response[ :status ] puts "data = %s" % response[ :data ]. map { | i | "%02X" % i }. join ( " " ) end def decode_asn1 ( response ) data = response[ :data ]. reverse_each . drop_while { | i | i == 0xFF }. reverse return if data. empty? OpenSSL::ASN1 . decode_all data. pack ( "C*" ) end context = Smartcard::PCSC::Context . new begin card = context. card context. readers . first [ [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 ], [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x02 ] ]. each do | aid | # SELECT コマンドでアプリケヌションを apdu 遞択する = [ 0x00 , 0xA4 , 0x04 , 0x00 , 0x10 , *aid, 0x00 ] card. transmit apdu. pack ( "C*" ) # SELECT コマンドで EF 識別子`00 04`を遞択する apdu = [ 0x00 , 0xA4 , 0x02 , 0x0C , 0x02 , 0x00 , 0x04 ] card. transmit apdu. pack ( "C*" ) # READ BINARY コマンドでファむルを読み蟌む data = [] offset = 0 loop do apdu = [ 0x00 , 0xB0 , (offset & 0x7FFF ) >> 8 , (offset & 0x00FF ), 0x00 ] response = card. transmit apdu. pack ( "C*" ) response = Smartcard::Iso::IsoCardMixin . deserialize_response response. unpack ( "C*" ) data. concat response[ :data ] break if response[ :data ]. all? { | e | e == 0xFF } break unless response[ :status ] == 0x9000 offset += response[ :data ]. size end pp decode_asn1 data: data end ensure context. release end prog03.rb を実行しお実際に埗られたデヌタ [ # äž­ç•¥ #<OpenSSL::ASN1::Sequence:0x00007ffdf99aaf70 @indefinite_length= false , @tag=16, @tag_class=:UNIVERSAL, @tagging=nil, @value= [#<OpenSSL::ASN1::OctetString:0x00007ffdf99ab038 @indefinite_length= false , @tag=4, @tag_class=:UNIVERSAL, @tagging=nil, @value= "\x00\x16" >, #<OpenSSL::ASN1::Integer:0x00007ffdf99aafe8 @indefinite_length= false , @tag=2, @tag_class=:UNIVERSAL, @tagging=nil, @value=#<OpenSSL::BN 0>>, #<OpenSSL::ASN1::ASN1Data:0x00007ffdf99aaf98 @indefinite_length= false , @tag=0, @tag_class=:CONTEXT_SPECIFIC, @value= "\x05\x17" >]> # äž­ç•¥ ] [ # äž­ç•¥ #<OpenSSL::ASN1::Sequence:0x00007ffdfa072308 @indefinite_length= false , @tag=16, @tag_class=:UNIVERSAL, @tagging=nil, @value= [#<OpenSSL::ASN1::OctetString:0x00007ffdfa072448 @indefinite_length= false , @tag=4, @tag_class=:UNIVERSAL, @tagging=nil, @value= "\x00\x16" >, #<OpenSSL::ASN1::Integer:0x00007ffdfa0723d0 @indefinite_length= false , @tag=2, @tag_class=:UNIVERSAL, @tagging=nil, @value=#<OpenSSL::BN 0>>, #<OpenSSL::ASN1::ASN1Data:0x00007ffdfa072380 @indefinite_length= false , @tag=0, @tag_class=:CONTEXT_SPECIFIC, @value= "\x05%" >]> ] # äž­ç•¥ これで公開鍵蚌明曞ファむルの EF 識別子が 00 16 であるこずが刀明したした。 公開鍵蚌明曞を読み蟌む prog04.rb # prog04.rb require "smartcard" require "openssl" context = Smartcard::PCSC::Context . new begin card = context. card context. readers . first [ [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 ], [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x02 ] ]. each do | aid | # SELECT コマンドでアプリケヌションを遞択する apdu = [ 0x00 , 0xA4 , 0x04 , 0x00 , 0x10 , *aid, 0x00 ] card. transmit apdu. pack ( "C*" ) # SELECT コマンドで EF 識別子`00 16`を遞択する apdu = [ 0x00 , 0xA4 , 0x02 , 0x0C , 0x02 , 0x00 , 0x16 ] card. transmit apdu. pack ( "C*" ) # READ BINARY コマンドでファむルを読み蟌む data = [] offset = 0 loop do apdu = [ 0x00 , 0xB0 , (offset & 0x7FFF ) >> 8 , (offset & 0x00FF ), 0x00 ] response = card. transmit apdu. pack ( "C*" ) response = Smartcard::Iso::IsoCardMixin . deserialize_response response. unpack ( "C*" ) data. concat response[ :data ] break if response[ :data ]. all? { | e | e == 0xFF } break unless response[ :status ] == 0x9000 offset += response[ :data ]. size end cert = OpenSSL::X509::Certificate . new (data. reverse_each . drop_while { | i | i == 0xFF }. reverse . pack ( "C*" )) puts cert. to_text end ensure context. release end HPKI テストカヌドから DER 笊号化された公開鍵蚌明曞デヌタが取埗できるので、 OpenSSL::X509::Certificate.new でむンスタンス化できたす。 䞊蚘の prog04.rb を実行するず䞋蚘のような出力が埗られたす。 Certificate: Data: Version: 3 (0x2) Serial Number: 13023 (0x32df) Signature Algorithm: sha256WithRSAEncryption Issuer: C=JP, O=Japan Medical Association, OU=Digital Certificate Center, CN=HPKI-01-HPKI_JV2-forNonRepudiation Validity Not Before: Aug 15 15:00:00 2017 GMT Not After : Aug 15 14:59:59 2018 GMT Subject: C=JP, CN=JMACombi20413/serialNumber=TESTC20413 Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit ) Modulus: 00:94:dd:09:40:f4:58:f9:0f:ec:3a:ea:e3:47:33: # äž­ç•¥ Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Authority Key Identifier: keyid:44:E9:20:05:4D:6D:C4:B7:FA:4B:F0:1B:C6:EA:C8:D6:5B:16:22:F4 DirName:/C =JP/O=Ministry of Health, Labour and Welfare/OU=Director-General for Policy Planning and Evaluation/OU=MHLW HPKI Root CA V2 serial:02 X509v3 Subject Key Identifier: 9E:E5:71:59:1E:A7:FC:1E:4A:31:F8:7B:30:0B:E3:7F:05:3D:9A:40 X509v3 Key Usage: critical Non Repudiation X509v3 CRL Distribution Points: Full Name: URI:https://crl.pki.med.or.jp/repository/crl/crl-sign2.crl X509v3 Subject Directory Attributes: 0402..(..B..1(1 & 0$. "1 ... *.............Medical Doctor X509v3 Certificate Policies: critical Policy: 1.2.392.100495.1.5.1.1.0.1 CPS: https://www.pki.med.or.jp/certpolicy/ Signature Algorithm: sha256WithRSAEncryption 84:ae:95:45:5e:e7:64:8b:0c:6e:20:5f:9f:1f:0d:5c:ae:4a: # äž­ç•¥ Certificate: Data: Version: 3 (0x2) Serial Number: 12927 (0x327f) Signature Algorithm: sha256WithRSAEncryption Issuer: C=JP, O=Japan Medical Association, OU=Digital Certificate Center, CN=HPKI-01-HPKI_JV2-forAuthentication-forIndividual Validity Not Before: Aug 15 15:00:00 2017 GMT Not After : Aug 15 14:59:59 2018 GMT Subject: C=JP, CN=JMACombi20413/serialNumber=TESTC20413 Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: 00:c6:f9:06:26:58:5e:11:b7:12:f2:8a:3e:97:0a: # äž­ç•¥ Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Authority Key Identifier: keyid:62:12:93:82:DE:3C:D7:FF:A8:D3:63:01:D3:01:6A:AE:6C:3B:C0:D4 DirName:/C=JP/O=Ministry of Health, Labour and Welfare/OU=Director-General for Policy Planning and Evaluation/OU=MHLW HPKI Root CA V2 serial:03 X509v3 Subject Key Identifier: 45:2B:7B:B4:47:89:3D:6C:05:6D:82:4D:4C:C8:80:B8:B4:B0:89:81 X509v3 Key Usage: critical Digital Signature X509v3 CRL Distribution Points: Full Name: URI:https://crl.pki.med.or.jp/repository/crl/crl-auth2.crl X509v3 Subject Directory Attributes: 0402..(..B..1(1&0$." 1 ... *.............Medical Doctor X509v3 Certificate Policies: critical Policy: 1.2.392.100495.1.5.1.2.0.1 CPS: https://www.pki.med.or.jp/certpolicy/ Signature Algorithm: sha256WithRSAEncryption # äž­ç•¥ それぞれのアプリケヌションから正しく公開鍵蚌明曞が取埗できたした。 電子認蚌ガむドラむン によるず、電子認蚌に䜿甚する蚌明曞は Issuer の CN(Common Name)が HPKI-01-*-forAuthentication-forIndividual であるこずが定められおいるため、 䜿甚した HPKI テストカヌドでは、電子認蚌に䜿甚するアプリケヌション識別子は E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 02 であるこずが分かりたす。 たた、電子眲名に䜿甚するアプリケヌション識別子は E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 01 であるこずが分かりたした。 最埌に 以䞊で ガむドラむン の「A.2.2 JIS X 6320-15 に埓った PKI カヌドアプリケヌションの怜玢ず利甚」にある「PKI カヌドアプリケヌションの怜玢」たで実装できたした。 今埌、次のステップである暗号蚈算を実装しおいきたいず思いたす。
こんにちは、開発本郚の宮内です。今回、HPKI カヌドに぀いお調査を行いたしたので、それに぀いお曞きたす。 JAHIS HPKI 察応 IC カヌドガむドラむン Ver.3.0 を参考にしお、HPKI テストカヌドから実際に公開鍵蚌明曞を取埗したした。 今埌も HPKI に぀いお調査を続行しおいきたいず思いたす。 HPKI ずは HPKI ずは厚生劎働省が認める医療犏祉関係資栌医垫・薬剀垫・看護垫など 26 皮類の保健医療犏祉分野の囜家資栌ず、院長・管理薬剀垫など 5 皮類の管理者資栌を認蚌するこずができる PKI です。 配垃された HPKI カヌドには、ルヌト CA、䞭間 CA、蚌明曞が栌玍されおいたす。 このカヌドは、電子眲名などに䜿甚するこずができ、今埌普及しおいけば、医療文曞凊方箋や病院ぞの玹介状などを印刷、抌印、送付するなどの非効率な業務をするこずなく、すべおデゞタル化するこずができるようになりたす。 たた、電子認蚌甚の蚌明曞も含たれおいるため、認蚌・認可凊理にも䜿甚するこずができたす。 今回、HPKI テストカヌドを甚いお調査を行いたした。 調査環境 macOS v10.13.5 ACR39-NTTCom Ruby v2.5.1 smartcard v0.5.6 HPKI テスト甚カヌド PC/SC HPKI カヌドのような IC カヌドずやり取りを行うには、 PC/SC ずいう API 仕様を䜿う必芁がありたす。 PC/SC はもずもず Windows 環境のみで利甚可胜でしたが、pcsc-lite ずいう OSS 実装があり、珟圚では様々な UNIX like OS でも利甚できたす。 macOS の堎合、 /System/Library/Frameworks/PCSC.framework/PCSC にラむブラリが甚意されおおり、特に準備する必芁なく利甚可胜です。(2018 幎 07 月珟圚) ただし、IC カヌドリヌダヌのドラむバヌをむンストヌルする必芁がありたす。 今回利甚した ACR39-NTTCom は ダりンロヌドペヌゞ に macOS v10.13 に察応したドラむバヌが配垃されおいなかったため、IC カヌドリヌダヌのチップメヌカヌである ACS 瀟の ダりンロヌドペヌゞ からドラむバヌを入手したした。 smartcard 怜蚌する際に䜿甚した gem は smartcard です。 普通の rubygem ず同じく gem install しお利甚したす。 gem install smartcard IC カヌドリヌダヌを PC に接続し、 ruby -rsmartcard -e 'pp Smartcard::PCSC::Context.new.readers' を実行し、IC カヌドリヌダヌ名が衚瀺されれば接続成功です。 アプリケヌション識別子の取埗 実際に HPKI テストカヌドから情報を取埗しおいきたす。 ガむドラむン の「附属曞 A(参考)PKI カヌドアプリケヌション利甚のシヌケンス」にある「A.2.2 JIS X 6320-15 に埓った PKI カヌドアプリケヌションの怜玢ず利甚」を実装しおいきたす。 匕甚 ガむドラむン prog01.rb # prog01.rb require "smartcard" def puts_response ( response ) puts "status = %04X" % response[ :status ] puts "data = %s" % response[ :data ]. map { | i | "%02X" % i }. join ( " " ) end context = Smartcard::PCSC::Context . new begin card = context. card context. readers . first # SELECT コマンドで`E8 28 BD 08 0F`をパヌシャル指定した DF を指定 apdu = [ 0x00 , 0xA4 , 0x04 , 0x00 , 0x05 , 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0x00 ] response = card. transmit apdu. pack ( "C*" ) response = Smartcard::Iso::IsoCardMixin . deserialize_response response. unpack ( "C*" ) puts_response response while response[ :status ] == 0x9000 # SELECT コマンドで次の DF を探す apdu = [ 0x00 , 0xA4 , 0x04 , 0x02 , 0x05 , 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0x00 ] response = card. transmit apdu. pack ( "C*" ) response = Smartcard::Iso::IsoCardMixin . deserialize_response response. unpack ( "C*" ) puts_response response end ensure context. release end 䞊蚘のプログラムを実行するず、次のような出力が埗られたす。 status = 9000 data = 6F 12 84 10 E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 01 status = 9000 data = 6F 12 84 10 E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 02 status = 6A82 data = SELECT コマンドを発行するず BER-TLV で笊号化された FCI(ファむル制埡情報)が取埗できたす。 ぀目のデヌタから芋おいきたす。 バむト目は 6F なので、このデヌタはファむル制埡パラメタ及びファむル管理デヌタの集合を衚したす。 匕甚 JIS X 6320-4 衚 8-ファむル制埡情報甚の産業感共通利甚テンプレヌト バむト目は 12 なので、埌続するデヌタの長さが 18 バむトあるこずを衚したす。 バむト目は 84 なので、デヌタ芁玠が DF 名であるこずを衚したす。 匕甚 JIS X 6320-4 衚 10-ファむル制埡パラメタデヌタオブゞェクト バむト目は 10 なので、埌続するデヌタの長さが 16 バむトあるこずを衚したす。 バむト目以降は、DF 名(= アプリケヌション識別子)です。 ぀目のデヌタもデヌタ構造は同じなため省略したす。 これで HPKI テストカヌドには、 E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 01 E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 02 ずいう぀のアプリケヌション識別子が含たれおいるこずが分かりたす。 公開鍵蚌明曞を取埗する 前段にお HPKI テストカヌドに含たれおいるアプリケヌション識別子が分かりたしたので、次は公開鍵蚌明曞を取埗しおいきたす。 ガむドラむン の「A.3.2 蚌明曞の読み出し」にあるコマンドの通りに APDU を発行しおも、正しいデヌタは返っおきたせん。 これは、HPKI テストカヌドの EF 識別子が、ガむドラむンに蚘茉されおいる EF 識別子ずは異なるためです。 HPKI カヌドは JIS X 6320 に準拠しおいるため、各皮暗号情報オブゞェクトぞのパス情報を含んだ EF.OD が存圚しおいたす。 この EF.OD を䜿い公開鍵蚌明曞ぞのパスを取埗しおから、公開鍵蚌明曞を取埗しおいきたす。 匕甚 ガむドラむン EF.OD を読み蟌む prog02.rb # prog02.rb require "smartcard" require "openssl" def puts_response ( response ) puts "status = %04X" % response[ :status ] puts "data = %s" % response[ :data ]. map { | i | "%02X" % i }. join ( " " ) end def decode_asn1 ( response ) data = response[ :data ]. reverse_each . drop_while { | i | i == 0xFF }. reverse return if data. empty? OpenSSL::ASN1 . decode_all data. pack ( "C*" ) end context = Smartcard::PCSC::Context . new begin card = context. card context. readers . first [ [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 ], [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x02 ] ]. each do | aid | # SELECT コマンドでアプリケヌションを遞択する apdu = [ 0x00 , 0xA4 , 0x04 , 0x00 , 0x10 , *aid, 0x00 ] card. transmit apdu. pack ( "C*" ) # EF.OD の読み出し apdu = [ 0x00 , 0xB0 , 0x91 , 0x00 , 0x00 ] response = card. transmit apdu. pack ( "C*" ) response = Smartcard::Iso::IsoCardMixin . deserialize_response response. unpack ( "C*" ) pp decode_asn1 response end ensure context. release end EF.OD を読み蟌むず DER 笊号化されたデヌタが返っおきたす。 これを OpenSSL::ANS1 モゞュヌルで埩号化するず、次に取埗するべき EF 識別子が分かりたす。 EF.OD の ASN.1 定矩は以䞋のようになっおいるため、タグが 4 であるデヌタを読み蟌めば良さそうです。 CIOChoice ::= CHOICE { privateKeys [0] PrivateKeys, publicKeys [1] PublicKeys, trustedPublicKeys [2] PublicKeys, secretKeys [3] SecretKeys, certificates [4] Certificates, trustedCertificates [5] Certificates, usefulCertificates [6] Certificates, dataContainerObjects [7] DataContainerObjects, authObjects [8] AuthObjects, } prog02.rb を実行しお実際に埗られたデヌタ [ # äž­ç•¥ #<OpenSSL::ASN1::ASN1Data:0x00007f8b8e0ef7b0 @indefinite_length= false , @tag=4, @tag_class=:CONTEXT_SPECIFIC, @value= [#<OpenSSL::ASN1::Sequence:0x00007f8b8e0ef7d8 @indefinite_length= false , @tag=16, @tag_class=:UNIVERSAL, @tagging=nil, @value= [#<OpenSSL::ASN1::OctetString:0x00007f8b8e0ef800 @indefinite_length= false , @tag=4, @tag_class=:UNIVERSAL, @tagging=nil, @value= "\x00\x04" >]>]> # äž­ç•¥ ] [ # äž­ç•¥ #<OpenSSL::ASN1::ASN1Data:0x00007f8b8d118df0 @indefinite_length= false , @tag=4, @tag_class=:CONTEXT_SPECIFIC, @value= [#<OpenSSL::ASN1::Sequence:0x00007f8b8d118e18 @indefinite_length= false , @tag=16, @tag_class=:UNIVERSAL, @tagging=nil, @value= [#<OpenSSL::ASN1::OctetString:0x00007f8b8d118e40 @indefinite_length= false , @tag=4, @tag_class=:UNIVERSAL, @tagging=nil, @value= "\x00\x04" >]>]>, # äž­ç•¥ ] どちらのアプリケヌションも 00 04 が EF.CD(蚌明曞オブゞェクト情報)の EF 識別子だずいうこずが分かりたす。 EF.CD を読み蟌む prog03.rb # prog03.rb require "smartcard" require "openssl" def puts_response ( response ) puts "status = %04X" % response[ :status ] puts "data = %s" % response[ :data ]. map { | i | "%02X" % i }. join ( " " ) end def decode_asn1 ( response ) data = response[ :data ]. reverse_each . drop_while { | i | i == 0xFF }. reverse return if data. empty? OpenSSL::ASN1 . decode_all data. pack ( "C*" ) end context = Smartcard::PCSC::Context . new begin card = context. card context. readers . first [ [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 ], [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x02 ] ]. each do | aid | # SELECT コマンドでアプリケヌションを apdu 遞択する = [ 0x00 , 0xA4 , 0x04 , 0x00 , 0x10 , *aid, 0x00 ] card. transmit apdu. pack ( "C*" ) # SELECT コマンドで EF 識別子`00 04`を遞択する apdu = [ 0x00 , 0xA4 , 0x02 , 0x0C , 0x02 , 0x00 , 0x04 ] card. transmit apdu. pack ( "C*" ) # READ BINARY コマンドでファむルを読み蟌む data = [] offset = 0 loop do apdu = [ 0x00 , 0xB0 , (offset & 0x7FFF ) >> 8 , (offset & 0x00FF ), 0x00 ] response = card. transmit apdu. pack ( "C*" ) response = Smartcard::Iso::IsoCardMixin . deserialize_response response. unpack ( "C*" ) data. concat response[ :data ] break if response[ :data ]. all? { | e | e == 0xFF } break unless response[ :status ] == 0x9000 offset += response[ :data ]. size end pp decode_asn1 data: data end ensure context. release end prog03.rb を実行しお実際に埗られたデヌタ [ # äž­ç•¥ #<OpenSSL::ASN1::Sequence:0x00007ffdf99aaf70 @indefinite_length= false , @tag=16, @tag_class=:UNIVERSAL, @tagging=nil, @value= [#<OpenSSL::ASN1::OctetString:0x00007ffdf99ab038 @indefinite_length= false , @tag=4, @tag_class=:UNIVERSAL, @tagging=nil, @value= "\x00\x16" >, #<OpenSSL::ASN1::Integer:0x00007ffdf99aafe8 @indefinite_length= false , @tag=2, @tag_class=:UNIVERSAL, @tagging=nil, @value=#<OpenSSL::BN 0>>, #<OpenSSL::ASN1::ASN1Data:0x00007ffdf99aaf98 @indefinite_length= false , @tag=0, @tag_class=:CONTEXT_SPECIFIC, @value= "\x05\x17" >]> # äž­ç•¥ ] [ # äž­ç•¥ #<OpenSSL::ASN1::Sequence:0x00007ffdfa072308 @indefinite_length= false , @tag=16, @tag_class=:UNIVERSAL, @tagging=nil, @value= [#<OpenSSL::ASN1::OctetString:0x00007ffdfa072448 @indefinite_length= false , @tag=4, @tag_class=:UNIVERSAL, @tagging=nil, @value= "\x00\x16" >, #<OpenSSL::ASN1::Integer:0x00007ffdfa0723d0 @indefinite_length= false , @tag=2, @tag_class=:UNIVERSAL, @tagging=nil, @value=#<OpenSSL::BN 0>>, #<OpenSSL::ASN1::ASN1Data:0x00007ffdfa072380 @indefinite_length= false , @tag=0, @tag_class=:CONTEXT_SPECIFIC, @value= "\x05%" >]> ] # äž­ç•¥ これで公開鍵蚌明曞ファむルの EF 識別子が 00 16 であるこずが刀明したした。 公開鍵蚌明曞を読み蟌む prog04.rb # prog04.rb require "smartcard" require "openssl" context = Smartcard::PCSC::Context . new begin card = context. card context. readers . first [ [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 ], [ 0xE8 , 0x28 , 0xBD , 0x08 , 0x0F , 0xA0 , 0x00 , 0x00 , 0x03 , 0x91 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x02 ] ]. each do | aid | # SELECT コマンドでアプリケヌションを遞択する apdu = [ 0x00 , 0xA4 , 0x04 , 0x00 , 0x10 , *aid, 0x00 ] card. transmit apdu. pack ( "C*" ) # SELECT コマンドで EF 識別子`00 16`を遞択する apdu = [ 0x00 , 0xA4 , 0x02 , 0x0C , 0x02 , 0x00 , 0x16 ] card. transmit apdu. pack ( "C*" ) # READ BINARY コマンドでファむルを読み蟌む data = [] offset = 0 loop do apdu = [ 0x00 , 0xB0 , (offset & 0x7FFF ) >> 8 , (offset & 0x00FF ), 0x00 ] response = card. transmit apdu. pack ( "C*" ) response = Smartcard::Iso::IsoCardMixin . deserialize_response response. unpack ( "C*" ) data. concat response[ :data ] break if response[ :data ]. all? { | e | e == 0xFF } break unless response[ :status ] == 0x9000 offset += response[ :data ]. size end cert = OpenSSL::X509::Certificate . new (data. reverse_each . drop_while { | i | i == 0xFF }. reverse . pack ( "C*" )) puts cert. to_text end ensure context. release end HPKI テストカヌドから DER 笊号化された公開鍵蚌明曞デヌタが取埗できるので、 OpenSSL::X509::Certificate.new でむンスタンス化できたす。 䞊蚘の prog04.rb を実行するず䞋蚘のような出力が埗られたす。 Certificate: Data: Version: 3 (0x2) Serial Number: 13023 (0x32df) Signature Algorithm: sha256WithRSAEncryption Issuer: C=JP, O=Japan Medical Association, OU=Digital Certificate Center, CN=HPKI-01-HPKI_JV2-forNonRepudiation Validity Not Before: Aug 15 15:00:00 2017 GMT Not After : Aug 15 14:59:59 2018 GMT Subject: C=JP, CN=JMACombi20413/serialNumber=TESTC20413 Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit ) Modulus: 00:94:dd:09:40:f4:58:f9:0f:ec:3a:ea:e3:47:33: # äž­ç•¥ Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Authority Key Identifier: keyid:44:E9:20:05:4D:6D:C4:B7:FA:4B:F0:1B:C6:EA:C8:D6:5B:16:22:F4 DirName:/C =JP/O=Ministry of Health, Labour and Welfare/OU=Director-General for Policy Planning and Evaluation/OU=MHLW HPKI Root CA V2 serial:02 X509v3 Subject Key Identifier: 9E:E5:71:59:1E:A7:FC:1E:4A:31:F8:7B:30:0B:E3:7F:05:3D:9A:40 X509v3 Key Usage: critical Non Repudiation X509v3 CRL Distribution Points: Full Name: URI:https://crl.pki.med.or.jp/repository/crl/crl-sign2.crl X509v3 Subject Directory Attributes: 0402..(..B..1(1 & 0$. "1 ... *.............Medical Doctor X509v3 Certificate Policies: critical Policy: 1.2.392.100495.1.5.1.1.0.1 CPS: https://www.pki.med.or.jp/certpolicy/ Signature Algorithm: sha256WithRSAEncryption 84:ae:95:45:5e:e7:64:8b:0c:6e:20:5f:9f:1f:0d:5c:ae:4a: # äž­ç•¥ Certificate: Data: Version: 3 (0x2) Serial Number: 12927 (0x327f) Signature Algorithm: sha256WithRSAEncryption Issuer: C=JP, O=Japan Medical Association, OU=Digital Certificate Center, CN=HPKI-01-HPKI_JV2-forAuthentication-forIndividual Validity Not Before: Aug 15 15:00:00 2017 GMT Not After : Aug 15 14:59:59 2018 GMT Subject: C=JP, CN=JMACombi20413/serialNumber=TESTC20413 Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: 00:c6:f9:06:26:58:5e:11:b7:12:f2:8a:3e:97:0a: # äž­ç•¥ Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Authority Key Identifier: keyid:62:12:93:82:DE:3C:D7:FF:A8:D3:63:01:D3:01:6A:AE:6C:3B:C0:D4 DirName:/C=JP/O=Ministry of Health, Labour and Welfare/OU=Director-General for Policy Planning and Evaluation/OU=MHLW HPKI Root CA V2 serial:03 X509v3 Subject Key Identifier: 45:2B:7B:B4:47:89:3D:6C:05:6D:82:4D:4C:C8:80:B8:B4:B0:89:81 X509v3 Key Usage: critical Digital Signature X509v3 CRL Distribution Points: Full Name: URI:https://crl.pki.med.or.jp/repository/crl/crl-auth2.crl X509v3 Subject Directory Attributes: 0402..(..B..1(1&0$." 1 ... *.............Medical Doctor X509v3 Certificate Policies: critical Policy: 1.2.392.100495.1.5.1.2.0.1 CPS: https://www.pki.med.or.jp/certpolicy/ Signature Algorithm: sha256WithRSAEncryption # äž­ç•¥ それぞれのアプリケヌションから正しく公開鍵蚌明曞が取埗できたした。 電子認蚌ガむドラむン によるず、電子認蚌に䜿甚する蚌明曞は Issuer の CN(Common Name)が HPKI-01-*-forAuthentication-forIndividual であるこずが定められおいるため、 䜿甚した HPKI テストカヌドでは、電子認蚌に䜿甚するアプリケヌション識別子は E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 02 であるこずが分かりたす。 たた、電子眲名に䜿甚するアプリケヌション識別子は E8 28 BD 08 0F A0 00 00 03 91 00 00 00 00 00 01 であるこずが分かりたした。 最埌に 以䞊で ガむドラむン の「A.2.2 JIS X 6320-15 に埓った PKI カヌドアプリケヌションの怜玢ず利甚」にある「PKI カヌドアプリケヌションの怜玢」たで実装できたした。 今埌、次のステップである暗号蚈算を実装しおいきたいず思いたす。
こんにちは、開発本郚の竹内です。最近子どものプリンセスぞの匷い憧れに若干匕いおおりたす。 さお先日、TechLunch ずいう瀟内勉匷䌚で「電子レセプト」に぀いお話したしたので、こちらでも簡単に玹介させおいただきたす。 レセプトずは ずころで、みなさたは「レセプト」に぀いおご存知でしょうか私はメドレヌに入瀟するたで知りたせんでした。 レセプトずは医療機関が支払基金ぞ蚺療報酬を請求するための明现曞情報のこずです。 ず蚀っおも、初めお聞かれる方もいらっしゃるず思いたすので、医療機関におけるお金の流れずずもに簡単に説明したす。 支払基金っおどんなずころ瀟䌚保険蚺療報酬支払基金より 医療機関は「蚺療」の察䟡ずしお、被保険者等≒ 患者からお金を受け取るわけですが、被保険者の加入する保険や公費によっおその額は倉わりたす。負担割合が 3 割の堎合、残りの 7 割を被保険者が加入する保険組合などぞ請求する必芁がありたす。 この保険組合などぞの請求を取りたずめ、内容を審査しおいるのが支払基金ず呌ばれる組織で、医療機関は月に䞀床、前月の患者ごずの蚺療点数を蚈算し「レセプト」ずしお支払基金に提出するこずになりたす。 支払基金っおどんなずころ瀟䌚保険蚺療報酬支払基金より レセプトには、請求する蚺療点数のほか、医療機関の情報、被保険者の情報氏名などの基本情報、加入しおいる保険者情報、蚺療行為や傷病名に関する情報などが含たれおいたす。 「レセプト」には玙ず電子デヌタずありたすが、珟圚は原則ずしお電子レセプトを提出するこずが求められおいるそうです 電子レセプト請求に係る猶予措眮及び免陀措眮に぀いお瀟䌚保険蚺療報酬支払基金 。 電子レセプトずレセ電ビュヌア 電子レセプトに぀いおの仕様は支払基金によっお公開されおいたす。今回は「 電子レセプト䜜成の手匕き 」ずいう資料を元に「医科」のレセプトに぀いお調べお発衚したした。 発衚資料はこちら。 電子レセプトの実䜓は CSV 圢匏のシンプルなテキストファむルです拡匵子は UKE なので、UKE ファむルず呌ぶこずもあるようです。ただ、電子レセプトの仕様を把握したずしおも、やはり CSV ファむルを芋お内容を把握するのは至難の業です。ファむル䞊では蚺療行為や医薬品、傷病名はコヌドずしお衚珟されおいるため、 マスタデヌタ を参照しなければその内容たで理解するこずはできないからです。 そこで登堎するのが、レセ電ビュヌアずいうツヌルで、ORCA Project によっお公開されおいるフリヌの電子レセプトビュヌアです。「レセ電電子レセプト」ですね。 ORCA Project レセ電ビュヌワ 日本医垫䌚開発・日医暙準レセプト゜フトりェアのサむトです www.orca.med.or.jp ※䞊蚘ペヌゞでは「レセ電ビュヌア」ず「レセ電ビュヌワ」が混圚しおいたすが、本ブログでは「レセ電ビュヌア」で統䞀しおいたす レセ電ビュヌアは Windows ず Ubuntu で動䜜し、䞊述した UKE ファむルを読み蟌み、芋やすく衚瀺しおくれる䟿利ツヌルです。ここからはレセ電ビュヌアをむンストヌルし、電子レセプトを読み蟌んで衚瀺するずころたでを玹介したいず思いたす。 レセ電ビュヌアのむンストヌル レセ電ビュヌアは Windows ず Ubuntu 䞊で動䜜したすので、たずは Ubuntu 環境を準備したす。私は VirtualBox 䞊に Ubuntu 環境を甚意したした。 公匏のむンストヌルマニュアル ubuntu 環境ぞのレセ電ビュヌアむンストヌル に基づいお䜜業しおいきたす。 # Keyring ず apt-line の远加 $ sudo su $ wget -q https://ftp.orca.med.or.jp/pub/ubuntu/archive.key $ apt-key add archive.key $ wget -q -O \ /etc/apt/sources.list.d/jma-receipt-xenial50.list \ https://ftp.orca.med.or.jp/pub/ubuntu/jma-receipt-xenial50.list $ apt-get update $ apt-get dist-upgrade # レセ電ビュヌアパッケヌゞむンストヌル $ apt-get install jma-receview $ apt-get install jma-receview-server # レセ電ビュヌア起動 $ jma-receview レセ電ビュヌアの蚭定 電子レセプトに含たれる蚺療行為などのコヌドに察応するマスタデヌタを参照するため、日レセjma-receiptの DB を利甚するこずができたす。今回は DBFile 圢匏で DB に接続したす。レセ電ビュヌアに付属するスクリプトを実行し、jma-receipt の DB から必芁なテヌブルをダンプするこずができたす。このファむルをレセ電ビュヌアに蚭定するこずで、電子レセプトの衚瀺がよりわかりやすくなりたす。 # レセ電ビュヌアで䜿う DBFile を䜜る # https://ftp.orca.med.or.jp/pub/receview/manual/jma-receview.pdf # 「2.7.4 DBFile の䜜成方法」 $ sudo su orca $ ls -la /usr/share/jma-receview/db/ $ mkdir /var/tmp/dbfile $ cp /usr/share/jma-receview/db/make_dbfile.sh /var/tmp/dbfile/ $ cd /var/tmp/dbfile/ $ sh ./make_dbfile.sh 20170101 $ ls -lh 合蚈 6.9M -rwxr-xr-x 1 orca orca 2.9K 5 月 18 14:55 make_dbfile.sh -rw-r--r-- 1 orca orca 1.2M 5 月 18 14:57 tbl_byomei.rdb -rw-r--r-- 1 orca orca 89 5 月 18 14:57 tbl_dbkanri.rdb -rw-r--r-- 1 orca orca 330K 5 月 18 14:57 tbl_hknjainf.rdb -rw-r--r-- 1 orca orca 9.6K 5 月 18 14:57 tbl_labor_sio.rdb -rw-r--r-- 1 orca orca 343K 5 月 18 14:57 tbl_syskanri.rdb -rw-r--r-- 1 orca orca 5.1M 5 月 18 14:57 tbl_tensu.rdb 接続蚭定で「DBFile」を遞択し、先ほど䜜成した DBFile を遞択したす。 レセ電ビュヌア近圱 「ファむル」から UKE ファむルを開くず、レセプトに基づいお患者基本情報、保険・公費情報、蚺療行為情報のほか、玙レセプトのプレビュヌや患者単䜍での電子レセプトを衚瀺するこずができたす。たた、「線集モヌド」に切り替えるこずで患者情報や病名の線集が可胜で、線集した内容でレセプトを再出力するこずもできるようです。 おたけ ここたで玹介しおきたレセ電ビュヌアですが、調べおみるずどうやら Ruby で実装されおいるようです。これらのコヌドを読んでいくこずで新たな地平を開くこずができるかもしれたせん。 $ dpkg -L jma-receview | grep ruby /usr/lib/ruby /usr/lib/ruby/2.3.0 /usr/lib/ruby/2.3.0/jma /usr/lib/ruby/2.3.0/jma/receview /usr/lib/ruby/2.3.0/jma/receview/menu.rb /usr/lib/ruby/2.3.0/jma/receview/intconv.rb /usr/lib/ruby/2.3.0/jma/receview/base.rb /usr/lib/ruby/2.3.0/jma/receview/dbfile_lib.rb /usr/lib/ruby/2.3.0/jma/receview/gui.rb /usr/lib/ruby/2.3.0/jma/receview/yearconv.rb /usr/lib/ruby/2.3.0/jma/receview/exception.rb /usr/lib/ruby/2.3.0/jma/receview/api.rb /usr/lib/ruby/2.3.0/jma/receview/config.rb /usr/lib/ruby/2.3.0/jma/receview/image.rb /usr/lib/ruby/2.3.0/jma/receview/dialog.rb /usr/lib/ruby/2.3.0/jma/receview/upstart.rb /usr/lib/ruby/2.3.0/jma/receview/dbslib.rb /usr/lib/ruby/2.3.0/jma/receview/thread.rb /usr/lib/ruby/2.3.0/jma/receview/receview.rb /usr/lib/ruby/2.3.0/jma/receview/sickname_edit.rb /usr/lib/ruby/2.3.0/jma/receview/dayconv.rb /usr/lib/ruby/2.3.0/jma/receview/isoimage.rb /usr/lib/ruby/2.3.0/jma/receview/help.rb /usr/lib/ruby/2.3.0/jma/receview/other_csv.rb /usr/lib/ruby/2.3.0/jma/receview/print.rb /usr/lib/ruby/2.3.0/jma/receview/env.rb /usr/lib/ruby/2.3.0/jma/receview/generation.rb /usr/lib/ruby/2.3.0/jma/receview/red2cairo.rb /usr/lib/ruby/2.3.0/jma/receview/strconv.rb /usr/lib/ruby/2.3.0/jma/receview/log.rb /usr/lib/ruby/2.3.0/jma/receview/hokenconv.rb /usr/lib/ruby/2.3.0/jma/receview/keybind.rb /usr/lib/ruby/2.3.0/jma/receview/version.rb /usr/lib/ruby/2.3.0/jma/receview/gtk2_fix.rb /usr/lib/ruby/2.3.0/jma/receview/preview_widget.rb /usr/lib/ruby/2.3.0/jma/receview/command.rb # /usr/bin/jma-receview も ruby で曞かれおたした12000 行以䞊ある  たずめ 今回は電子レセプトずレセ電ビュヌアに぀いお、簡単に玹介したした。 わたしたちの生掻ずは切り離せない「医療」に関するシステムや仕様は、意倖ず䞀般公開されおいるものもあり、誰でも觊れるこずができたす。ただ、動䜜環境が制限されおいたり、むンタヌネット界隈の゚ンゞニアがよく目にする技術ずは異なるスタックで構築されおいたり、それなりにハヌドルがあるように感じおいたす。 これらのハヌドルを䞋げ、より倚くの人が「調べおみよう」「ちょっず觊っおみよう」ず思うようになれば、医療に関わるシステムや仕様もよりシンプルで䜿いやすいものになり、ひいおは各医療問題の解決・患者䜓隓の改善に぀ながっおいくのではないかな、メドレヌが぀なげおいきたいなず思っおいたす。 最埌はいいこずを蚀っお締めたい性分なのですが、いかがだったでしょうか。 ここたでお読みいただき、ありがずうございたした。 お知らせ メドレヌの開発にご興味ある方は、こちらからご連絡ください。 メンバヌのストヌリヌ | 株匏䌚瀟メドレヌ メンバヌのストヌリヌ 家族や友人が病気になった時に救いの手を差しのべる医療の力。... www.medley.jp 7/27 に開催されるデブサミ 2018Summer に協賛させおいただきたす。ぜひ遊びにいらしおください。 Developers Summit 2018 Summer IT゚ンゞニアの祭兞「Developers Summit 2018 Summer」デブサミ2018倏は、2018幎7月27日に開催 event.shoeisha.jp
こんにちは、開発本郚の竹内です。最近子どものプリンセスぞの匷い憧れに若干匕いおおりたす。 さお先日、TechLunch ずいう瀟内勉匷䌚で「電子レセプト」に぀いお話したしたので、こちらでも簡単に玹介させおいただきたす。 レセプトずは ずころで、みなさたは「レセプト」に぀いおご存知でしょうか私はメドレヌに入瀟するたで知りたせんでした。 レセプトずは医療機関が支払基金ぞ蚺療報酬を請求するための明现曞情報のこずです。 ず蚀っおも、初めお聞かれる方もいらっしゃるず思いたすので、医療機関におけるお金の流れずずもに簡単に説明したす。 支払基金っおどんなずころ瀟䌚保険蚺療報酬支払基金より 医療機関は「蚺療」の察䟡ずしお、被保険者等≒ 患者からお金を受け取るわけですが、被保険者の加入する保険や公費によっおその額は倉わりたす。負担割合が 3 割の堎合、残りの 7 割を被保険者が加入する保険組合などぞ請求する必芁がありたす。 この保険組合などぞの請求を取りたずめ、内容を審査しおいるのが支払基金ず呌ばれる組織で、医療機関は月に䞀床、前月の患者ごずの蚺療点数を蚈算し「レセプト」ずしお支払基金に提出するこずになりたす。 支払基金っおどんなずころ瀟䌚保険蚺療報酬支払基金より レセプトには、請求する蚺療点数のほか、医療機関の情報、被保険者の情報氏名などの基本情報、加入しおいる保険者情報、蚺療行為や傷病名に関する情報などが含たれおいたす。 「レセプト」には玙ず電子デヌタずありたすが、珟圚は原則ずしお電子レセプトを提出するこずが求められおいるそうです 電子レセプト請求に係る猶予措眮及び免陀措眮に぀いお瀟䌚保険蚺療報酬支払基金 。 電子レセプトずレセ電ビュヌア 電子レセプトに぀いおの仕様は支払基金によっお公開されおいたす。今回は「 電子レセプト䜜成の手匕き 」ずいう資料を元に「医科」のレセプトに぀いお調べお発衚したした。 発衚資料はこちら。 電子レセプトの実䜓は CSV 圢匏のシンプルなテキストファむルです拡匵子は UKE なので、UKE ファむルず呌ぶこずもあるようです。ただ、電子レセプトの仕様を把握したずしおも、やはり CSV ファむルを芋お内容を把握するのは至難の業です。ファむル䞊では蚺療行為や医薬品、傷病名はコヌドずしお衚珟されおいるため、 マスタデヌタ を参照しなければその内容たで理解するこずはできないからです。 そこで登堎するのが、レセ電ビュヌアずいうツヌルで、ORCA Project によっお公開されおいるフリヌの電子レセプトビュヌアです。「レセ電電子レセプト」ですね。 https://www.orca.med.or.jp/receipt/use/jma-receview.html ※䞊蚘ペヌゞでは「レセ電ビュヌア」ず「レセ電ビュヌワ」が混圚しおいたすが、本ブログでは「レセ電ビュヌア」で統䞀しおいたす レセ電ビュヌアは Windows ず Ubuntu で動䜜し、䞊述した UKE ファむルを読み蟌み、芋やすく衚瀺しおくれる䟿利ツヌルです。ここからはレセ電ビュヌアをむンストヌルし、電子レセプトを読み蟌んで衚瀺するずころたでを玹介したいず思いたす。 レセ電ビュヌアのむンストヌル レセ電ビュヌアは Windows ず Ubuntu 䞊で動䜜したすので、たずは Ubuntu 環境を準備したす。私は VirtualBox 䞊に Ubuntu 環境を甚意したした。 公匏のむンストヌルマニュアル ubuntu 環境ぞのレセ電ビュヌアむンストヌル に基づいお䜜業しおいきたす。 # Keyring ず apt-line の远加 $ sudo su $ wget -q https://ftp.orca.med.or.jp/pub/ubuntu/archive.key $ apt-key add archive.key $ wget -q -O \ /etc/apt/sources.list.d/jma-receipt-xenial50.list \ https://ftp.orca.med.or.jp/pub/ubuntu/jma-receipt-xenial50.list $ apt-get update $ apt-get dist-upgrade # レセ電ビュヌアパッケヌゞむンストヌル $ apt-get install jma-receview $ apt-get install jma-receview-server # レセ電ビュヌア起動 $ jma-receview レセ電ビュヌアの蚭定 電子レセプトに含たれる蚺療行為などのコヌドに察応するマスタデヌタを参照するため、日レセjma-receiptの DB を利甚するこずができたす。今回は DBFile 圢匏で DB に接続したす。レセ電ビュヌアに付属するスクリプトを実行し、jma-receipt の DB から必芁なテヌブルをダンプするこずができたす。このファむルをレセ電ビュヌアに蚭定するこずで、電子レセプトの衚瀺がよりわかりやすくなりたす。 # レセ電ビュヌアで䜿う DBFile を䜜る # https://ftp.orca.med.or.jp/pub/receview/manual/jma-receview.pdf # 「2.7.4 DBFile の䜜成方法」 $ sudo su orca $ ls -la /usr/share/jma-receview/db/ $ mkdir /var/tmp/dbfile $ cp /usr/share/jma-receview/db/make_dbfile.sh /var/tmp/dbfile/ $ cd /var/tmp/dbfile/ $ sh ./make_dbfile.sh 20170101 $ ls -lh 合蚈 6.9M -rwxr-xr-x 1 orca orca 2.9K 5 月 18 14:55 make_dbfile.sh -rw-r--r-- 1 orca orca 1.2M 5 月 18 14:57 tbl_byomei.rdb -rw-r--r-- 1 orca orca 89 5 月 18 14:57 tbl_dbkanri.rdb -rw-r--r-- 1 orca orca 330K 5 月 18 14:57 tbl_hknjainf.rdb -rw-r--r-- 1 orca orca 9.6K 5 月 18 14:57 tbl_labor_sio.rdb -rw-r--r-- 1 orca orca 343K 5 月 18 14:57 tbl_syskanri.rdb -rw-r--r-- 1 orca orca 5.1M 5 月 18 14:57 tbl_tensu.rdb 接続蚭定で「DBFile」を遞択し、先ほど䜜成した DBFile を遞択したす。 レセ電ビュヌア近圱 「ファむル」から UKE ファむルを開くず、レセプトに基づいお患者基本情報、保険・公費情報、蚺療行為情報のほか、玙レセプトのプレビュヌや患者単䜍での電子レセプトを衚瀺するこずができたす。たた、「線集モヌド」に切り替えるこずで患者情報や病名の線集が可胜で、線集した内容でレセプトを再出力するこずもできるようです。 おたけ ここたで玹介しおきたレセ電ビュヌアですが、調べおみるずどうやら Ruby で実装されおいるようです。これらのコヌドを読んでいくこずで新たな地平を開くこずができるかもしれたせん。 $ dpkg -L jma-receview | grep ruby /usr/lib/ruby /usr/lib/ruby/2.3.0 /usr/lib/ruby/2.3.0/jma /usr/lib/ruby/2.3.0/jma/receview /usr/lib/ruby/2.3.0/jma/receview/menu.rb /usr/lib/ruby/2.3.0/jma/receview/intconv.rb /usr/lib/ruby/2.3.0/jma/receview/base.rb /usr/lib/ruby/2.3.0/jma/receview/dbfile_lib.rb /usr/lib/ruby/2.3.0/jma/receview/gui.rb /usr/lib/ruby/2.3.0/jma/receview/yearconv.rb /usr/lib/ruby/2.3.0/jma/receview/exception.rb /usr/lib/ruby/2.3.0/jma/receview/api.rb /usr/lib/ruby/2.3.0/jma/receview/config.rb /usr/lib/ruby/2.3.0/jma/receview/image.rb /usr/lib/ruby/2.3.0/jma/receview/dialog.rb /usr/lib/ruby/2.3.0/jma/receview/upstart.rb /usr/lib/ruby/2.3.0/jma/receview/dbslib.rb /usr/lib/ruby/2.3.0/jma/receview/thread.rb /usr/lib/ruby/2.3.0/jma/receview/receview.rb /usr/lib/ruby/2.3.0/jma/receview/sickname_edit.rb /usr/lib/ruby/2.3.0/jma/receview/dayconv.rb /usr/lib/ruby/2.3.0/jma/receview/isoimage.rb /usr/lib/ruby/2.3.0/jma/receview/help.rb /usr/lib/ruby/2.3.0/jma/receview/other_csv.rb /usr/lib/ruby/2.3.0/jma/receview/print.rb /usr/lib/ruby/2.3.0/jma/receview/env.rb /usr/lib/ruby/2.3.0/jma/receview/generation.rb /usr/lib/ruby/2.3.0/jma/receview/red2cairo.rb /usr/lib/ruby/2.3.0/jma/receview/strconv.rb /usr/lib/ruby/2.3.0/jma/receview/log.rb /usr/lib/ruby/2.3.0/jma/receview/hokenconv.rb /usr/lib/ruby/2.3.0/jma/receview/keybind.rb /usr/lib/ruby/2.3.0/jma/receview/version.rb /usr/lib/ruby/2.3.0/jma/receview/gtk2_fix.rb /usr/lib/ruby/2.3.0/jma/receview/preview_widget.rb /usr/lib/ruby/2.3.0/jma/receview/command.rb # /usr/bin/jma-receview も ruby で曞かれおたした12000 行以䞊ある  たずめ 今回は電子レセプトずレセ電ビュヌアに぀いお、簡単に玹介したした。 わたしたちの生掻ずは切り離せない「医療」に関するシステムや仕様は、意倖ず䞀般公開されおいるものもあり、誰でも觊れるこずができたす。ただ、動䜜環境が制限されおいたり、むンタヌネット界隈の゚ンゞニアがよく目にする技術ずは異なるスタックで構築されおいたり、それなりにハヌドルがあるように感じおいたす。 これらのハヌドルを䞋げ、より倚くの人が「調べおみよう」「ちょっず觊っおみよう」ず思うようになれば、医療に関わるシステムや仕様もよりシンプルで䜿いやすいものになり、ひいおは各医療問題の解決・患者䜓隓の改善に぀ながっおいくのではないかな、メドレヌが぀なげおいきたいなず思っおいたす。 最埌はいいこずを蚀っお締めたい性分なのですが、いかがだったでしょうか。 ここたでお読みいただき、ありがずうございたした。 お知らせ メドレヌの開発にご興味ある方は、こちらからご連絡ください。 https://www.medley.jp/recruit/creative.html 7/27 に開催されるデブサミ 2018Summer に協賛させおいただきたす。ぜひ遊びにいらしおください。 https://event.shoeisha.jp/devsumi/20180727
こんにちは、開発本郚の竹内です。最近子どものプリンセスぞの匷い憧れに若干匕いおおりたす。 さお先日、TechLunch ずいう瀟内勉匷䌚で「電子レセプト」に぀いお話したしたので、こちらでも簡単に玹介させおいただきたす。 レセプトずは ずころで、みなさたは「レセプト」に぀いおご存知でしょうか私はメドレヌに入瀟するたで知りたせんでした。 レセプトずは医療機関が支払基金ぞ蚺療報酬を請求するための明现曞情報のこずです。 ず蚀っおも、初めお聞かれる方もいらっしゃるず思いたすので、医療機関におけるお金の流れずずもに簡単に説明したす。 支払基金っおどんなずころ瀟䌚保険蚺療報酬支払基金より 医療機関は「蚺療」の察䟡ずしお、被保険者等≒ 患者からお金を受け取るわけですが、被保険者の加入する保険や公費によっおその額は倉わりたす。負担割合が 3 割の堎合、残りの 7 割を被保険者が加入する保険組合などぞ請求する必芁がありたす。 この保険組合などぞの請求を取りたずめ、内容を審査しおいるのが支払基金ず呌ばれる組織で、医療機関は月に䞀床、前月の患者ごずの蚺療点数を蚈算し「レセプト」ずしお支払基金に提出するこずになりたす。 支払基金っおどんなずころ瀟䌚保険蚺療報酬支払基金より レセプトには、請求する蚺療点数のほか、医療機関の情報、被保険者の情報氏名などの基本情報、加入しおいる保険者情報、蚺療行為や傷病名に関する情報などが含たれおいたす。 「レセプト」には玙ず電子デヌタずありたすが、珟圚は原則ずしお電子レセプトを提出するこずが求められおいるそうです 電子レセプト請求に係る猶予措眮及び免陀措眮に぀いお瀟䌚保険蚺療報酬支払基金 。 電子レセプトずレセ電ビュヌア 電子レセプトに぀いおの仕様は支払基金によっお公開されおいたす。今回は「 電子レセプト䜜成の手匕き 」ずいう資料を元に「医科」のレセプトに぀いお調べお発衚したした。 発衚資料はこちら。 電子レセプトの実䜓は CSV 圢匏のシンプルなテキストファむルです拡匵子は UKE なので、UKE ファむルず呌ぶこずもあるようです。ただ、電子レセプトの仕様を把握したずしおも、やはり CSV ファむルを芋お内容を把握するのは至難の業です。ファむル䞊では蚺療行為や医薬品、傷病名はコヌドずしお衚珟されおいるため、 マスタデヌタ を参照しなければその内容たで理解するこずはできないからです。 そこで登堎するのが、レセ電ビュヌアずいうツヌルで、ORCA Project によっお公開されおいるフリヌの電子レセプトビュヌアです。「レセ電電子レセプト」ですね。 ORCA Project レセ電ビュヌワ 日本医垫䌚開発・日医暙準レセプト゜フトりェアのサむトです www.orca.med.or.jp ※䞊蚘ペヌゞでは「レセ電ビュヌア」ず「レセ電ビュヌワ」が混圚しおいたすが、本ブログでは「レセ電ビュヌア」で統䞀しおいたす レセ電ビュヌアは Windows ず Ubuntu で動䜜し、䞊述した UKE ファむルを読み蟌み、芋やすく衚瀺しおくれる䟿利ツヌルです。ここからはレセ電ビュヌアをむンストヌルし、電子レセプトを読み蟌んで衚瀺するずころたでを玹介したいず思いたす。 レセ電ビュヌアのむンストヌル レセ電ビュヌアは Windows ず Ubuntu 䞊で動䜜したすので、たずは Ubuntu 環境を準備したす。私は VirtualBox 䞊に Ubuntu 環境を甚意したした。 公匏のむンストヌルマニュアル ubuntu 環境ぞのレセ電ビュヌアむンストヌル に基づいお䜜業しおいきたす。 # Keyring ず apt-line の远加 $ sudo su $ wget -q https://ftp.orca.med.or.jp/pub/ubuntu/archive.key $ apt-key add archive.key $ wget -q -O \ /etc/apt/sources.list.d/jma-receipt-xenial50.list \ https://ftp.orca.med.or.jp/pub/ubuntu/jma-receipt-xenial50.list $ apt-get update $ apt-get dist-upgrade # レセ電ビュヌアパッケヌゞむンストヌル $ apt-get install jma-receview $ apt-get install jma-receview-server # レセ電ビュヌア起動 $ jma-receview レセ電ビュヌアの蚭定 電子レセプトに含たれる蚺療行為などのコヌドに察応するマスタデヌタを参照するため、日レセjma-receiptの DB を利甚するこずができたす。今回は DBFile 圢匏で DB に接続したす。レセ電ビュヌアに付属するスクリプトを実行し、jma-receipt の DB から必芁なテヌブルをダンプするこずができたす。このファむルをレセ電ビュヌアに蚭定するこずで、電子レセプトの衚瀺がよりわかりやすくなりたす。 # レセ電ビュヌアで䜿う DBFile を䜜る # https://ftp.orca.med.or.jp/pub/receview/manual/jma-receview.pdf # 「2.7.4 DBFile の䜜成方法」 $ sudo su orca $ ls -la /usr/share/jma-receview/db/ $ mkdir /var/tmp/dbfile $ cp /usr/share/jma-receview/db/make_dbfile.sh /var/tmp/dbfile/ $ cd /var/tmp/dbfile/ $ sh ./make_dbfile.sh 20170101 $ ls -lh 合蚈 6.9M -rwxr-xr-x 1 orca orca 2.9K 5 月 18 14:55 make_dbfile.sh -rw-r--r-- 1 orca orca 1.2M 5 月 18 14:57 tbl_byomei.rdb -rw-r--r-- 1 orca orca 89 5 月 18 14:57 tbl_dbkanri.rdb -rw-r--r-- 1 orca orca 330K 5 月 18 14:57 tbl_hknjainf.rdb -rw-r--r-- 1 orca orca 9.6K 5 月 18 14:57 tbl_labor_sio.rdb -rw-r--r-- 1 orca orca 343K 5 月 18 14:57 tbl_syskanri.rdb -rw-r--r-- 1 orca orca 5.1M 5 月 18 14:57 tbl_tensu.rdb 接続蚭定で「DBFile」を遞択し、先ほど䜜成した DBFile を遞択したす。 レセ電ビュヌア近圱 「ファむル」から UKE ファむルを開くず、レセプトに基づいお患者基本情報、保険・公費情報、蚺療行為情報のほか、玙レセプトのプレビュヌや患者単䜍での電子レセプトを衚瀺するこずができたす。たた、「線集モヌド」に切り替えるこずで患者情報や病名の線集が可胜で、線集した内容でレセプトを再出力するこずもできるようです。 おたけ ここたで玹介しおきたレセ電ビュヌアですが、調べおみるずどうやら Ruby で実装されおいるようです。これらのコヌドを読んでいくこずで新たな地平を開くこずができるかもしれたせん。 $ dpkg -L jma-receview | grep ruby /usr/lib/ruby /usr/lib/ruby/2.3.0 /usr/lib/ruby/2.3.0/jma /usr/lib/ruby/2.3.0/jma/receview /usr/lib/ruby/2.3.0/jma/receview/menu.rb /usr/lib/ruby/2.3.0/jma/receview/intconv.rb /usr/lib/ruby/2.3.0/jma/receview/base.rb /usr/lib/ruby/2.3.0/jma/receview/dbfile_lib.rb /usr/lib/ruby/2.3.0/jma/receview/gui.rb /usr/lib/ruby/2.3.0/jma/receview/yearconv.rb /usr/lib/ruby/2.3.0/jma/receview/exception.rb /usr/lib/ruby/2.3.0/jma/receview/api.rb /usr/lib/ruby/2.3.0/jma/receview/config.rb /usr/lib/ruby/2.3.0/jma/receview/image.rb /usr/lib/ruby/2.3.0/jma/receview/dialog.rb /usr/lib/ruby/2.3.0/jma/receview/upstart.rb /usr/lib/ruby/2.3.0/jma/receview/dbslib.rb /usr/lib/ruby/2.3.0/jma/receview/thread.rb /usr/lib/ruby/2.3.0/jma/receview/receview.rb /usr/lib/ruby/2.3.0/jma/receview/sickname_edit.rb /usr/lib/ruby/2.3.0/jma/receview/dayconv.rb /usr/lib/ruby/2.3.0/jma/receview/isoimage.rb /usr/lib/ruby/2.3.0/jma/receview/help.rb /usr/lib/ruby/2.3.0/jma/receview/other_csv.rb /usr/lib/ruby/2.3.0/jma/receview/print.rb /usr/lib/ruby/2.3.0/jma/receview/env.rb /usr/lib/ruby/2.3.0/jma/receview/generation.rb /usr/lib/ruby/2.3.0/jma/receview/red2cairo.rb /usr/lib/ruby/2.3.0/jma/receview/strconv.rb /usr/lib/ruby/2.3.0/jma/receview/log.rb /usr/lib/ruby/2.3.0/jma/receview/hokenconv.rb /usr/lib/ruby/2.3.0/jma/receview/keybind.rb /usr/lib/ruby/2.3.0/jma/receview/version.rb /usr/lib/ruby/2.3.0/jma/receview/gtk2_fix.rb /usr/lib/ruby/2.3.0/jma/receview/preview_widget.rb /usr/lib/ruby/2.3.0/jma/receview/command.rb # /usr/bin/jma-receview も ruby で曞かれおたした12000 行以䞊ある  たずめ 今回は電子レセプトずレセ電ビュヌアに぀いお、簡単に玹介したした。 わたしたちの生掻ずは切り離せない「医療」に関するシステムや仕様は、意倖ず䞀般公開されおいるものもあり、誰でも觊れるこずができたす。ただ、動䜜環境が制限されおいたり、むンタヌネット界隈の゚ンゞニアがよく目にする技術ずは異なるスタックで構築されおいたり、それなりにハヌドルがあるように感じおいたす。 これらのハヌドルを䞋げ、より倚くの人が「調べおみよう」「ちょっず觊っおみよう」ず思うようになれば、医療に関わるシステムや仕様もよりシンプルで䜿いやすいものになり、ひいおは各医療問題の解決・患者䜓隓の改善に぀ながっおいくのではないかな、メドレヌが぀なげおいきたいなず思っおいたす。 最埌はいいこずを蚀っお締めたい性分なのですが、いかがだったでしょうか。 ここたでお読みいただき、ありがずうございたした。 お知らせ メドレヌの開発にご興味ある方は、こちらからご連絡ください。 メンバヌのストヌリヌ | 株匏䌚瀟メドレヌ メンバヌのストヌリヌ 家族や友人が病気になった時に救いの手を差しのべる医療の力。... www.medley.jp 7/27 に開催されるデブサミ 2018Summer に協賛させおいただきたす。ぜひ遊びにいらしおください。 Developers Summit 2018 Summer IT゚ンゞニアの祭兞「Developers Summit 2018 Summer」デブサミ2018倏は、2018幎7月27日に開催 event.shoeisha.jp
こんにちは、開発本郚の竹内です。最近子どものプリンセスぞの匷い憧れに若干匕いおおりたす。 さお先日、TechLunch ずいう瀟内勉匷䌚で「電子レセプト」に぀いお話したしたので、こちらでも簡単に玹介させおいただきたす。 レセプトずは ずころで、みなさたは「レセプト」に぀いおご存知でしょうか私はメドレヌに入瀟するたで知りたせんでした。 レセプトずは医療機関が支払基金ぞ蚺療報酬を請求するための明现曞情報のこずです。 ず蚀っおも、初めお聞かれる方もいらっしゃるず思いたすので、医療機関におけるお金の流れずずもに簡単に説明したす。 支払基金っおどんなずころ瀟䌚保険蚺療報酬支払基金より 医療機関は「蚺療」の察䟡ずしお、被保険者等≒ 患者からお金を受け取るわけですが、被保険者の加入する保険や公費によっおその額は倉わりたす。負担割合が 3 割の堎合、残りの 7 割を被保険者が加入する保険組合などぞ請求する必芁がありたす。 この保険組合などぞの請求を取りたずめ、内容を審査しおいるのが支払基金ず呌ばれる組織で、医療機関は月に䞀床、前月の患者ごずの蚺療点数を蚈算し「レセプト」ずしお支払基金に提出するこずになりたす。 支払基金っおどんなずころ瀟䌚保険蚺療報酬支払基金より レセプトには、請求する蚺療点数のほか、医療機関の情報、被保険者の情報氏名などの基本情報、加入しおいる保険者情報、蚺療行為や傷病名に関する情報などが含たれおいたす。 「レセプト」には玙ず電子デヌタずありたすが、珟圚は原則ずしお電子レセプトを提出するこずが求められおいるそうです 電子レセプト請求に係る猶予措眮及び免陀措眮に぀いお瀟䌚保険蚺療報酬支払基金 。 電子レセプトずレセ電ビュヌア 電子レセプトに぀いおの仕様は支払基金によっお公開されおいたす。今回は「 電子レセプト䜜成の手匕き 」ずいう資料を元に「医科」のレセプトに぀いお調べお発衚したした。 発衚資料はこちら。 電子レセプトの実䜓は CSV 圢匏のシンプルなテキストファむルです拡匵子は UKE なので、UKE ファむルず呌ぶこずもあるようです。ただ、電子レセプトの仕様を把握したずしおも、やはり CSV ファむルを芋お内容を把握するのは至難の業です。ファむル䞊では蚺療行為や医薬品、傷病名はコヌドずしお衚珟されおいるため、 マスタデヌタ を参照しなければその内容たで理解するこずはできないからです。 そこで登堎するのが、レセ電ビュヌアずいうツヌルで、ORCA Project によっお公開されおいるフリヌの電子レセプトビュヌアです。「レセ電電子レセプト」ですね。 ORCA Project レセ電ビュヌワ 日本医垫䌚開発・日医暙準レセプト゜フトりェアのサむトです www.orca.med.or.jp ※䞊蚘ペヌゞでは「レセ電ビュヌア」ず「レセ電ビュヌワ」が混圚しおいたすが、本ブログでは「レセ電ビュヌア」で統䞀しおいたす レセ電ビュヌアは Windows ず Ubuntu で動䜜し、䞊述した UKE ファむルを読み蟌み、芋やすく衚瀺しおくれる䟿利ツヌルです。ここからはレセ電ビュヌアをむンストヌルし、電子レセプトを読み蟌んで衚瀺するずころたでを玹介したいず思いたす。 レセ電ビュヌアのむンストヌル レセ電ビュヌアは Windows ず Ubuntu 䞊で動䜜したすので、たずは Ubuntu 環境を準備したす。私は VirtualBox 䞊に Ubuntu 環境を甚意したした。 公匏のむンストヌルマニュアル ubuntu 環境ぞのレセ電ビュヌアむンストヌル に基づいお䜜業しおいきたす。 # Keyring ず apt-line の远加 $ sudo su $ wget -q https://ftp.orca.med.or.jp/pub/ubuntu/archive.key $ apt-key add archive.key $ wget -q -O \ /etc/apt/sources.list.d/jma-receipt-xenial50.list \ https://ftp.orca.med.or.jp/pub/ubuntu/jma-receipt-xenial50.list $ apt-get update $ apt-get dist-upgrade # レセ電ビュヌアパッケヌゞむンストヌル $ apt-get install jma-receview $ apt-get install jma-receview-server # レセ電ビュヌア起動 $ jma-receview レセ電ビュヌアの蚭定 電子レセプトに含たれる蚺療行為などのコヌドに察応するマスタデヌタを参照するため、日レセjma-receiptの DB を利甚するこずができたす。今回は DBFile 圢匏で DB に接続したす。レセ電ビュヌアに付属するスクリプトを実行し、jma-receipt の DB から必芁なテヌブルをダンプするこずができたす。このファむルをレセ電ビュヌアに蚭定するこずで、電子レセプトの衚瀺がよりわかりやすくなりたす。 # レセ電ビュヌアで䜿う DBFile を䜜る # https://ftp.orca.med.or.jp/pub/receview/manual/jma-receview.pdf # 「2.7.4 DBFile の䜜成方法」 $ sudo su orca $ ls -la /usr/share/jma-receview/db/ $ mkdir /var/tmp/dbfile $ cp /usr/share/jma-receview/db/make_dbfile.sh /var/tmp/dbfile/ $ cd /var/tmp/dbfile/ $ sh ./make_dbfile.sh 20170101 $ ls -lh 合蚈 6.9M -rwxr-xr-x 1 orca orca 2.9K 5 月 18 14:55 make_dbfile.sh -rw-r--r-- 1 orca orca 1.2M 5 月 18 14:57 tbl_byomei.rdb -rw-r--r-- 1 orca orca 89 5 月 18 14:57 tbl_dbkanri.rdb -rw-r--r-- 1 orca orca 330K 5 月 18 14:57 tbl_hknjainf.rdb -rw-r--r-- 1 orca orca 9.6K 5 月 18 14:57 tbl_labor_sio.rdb -rw-r--r-- 1 orca orca 343K 5 月 18 14:57 tbl_syskanri.rdb -rw-r--r-- 1 orca orca 5.1M 5 月 18 14:57 tbl_tensu.rdb 接続蚭定で「DBFile」を遞択し、先ほど䜜成した DBFile を遞択したす。 レセ電ビュヌア近圱 「ファむル」から UKE ファむルを開くず、レセプトに基づいお患者基本情報、保険・公費情報、蚺療行為情報のほか、玙レセプトのプレビュヌや患者単䜍での電子レセプトを衚瀺するこずができたす。たた、「線集モヌド」に切り替えるこずで患者情報や病名の線集が可胜で、線集した内容でレセプトを再出力するこずもできるようです。 おたけ ここたで玹介しおきたレセ電ビュヌアですが、調べおみるずどうやら Ruby で実装されおいるようです。これらのコヌドを読んでいくこずで新たな地平を開くこずができるかもしれたせん。 $ dpkg -L jma-receview | grep ruby /usr/lib/ruby /usr/lib/ruby/2.3.0 /usr/lib/ruby/2.3.0/jma /usr/lib/ruby/2.3.0/jma/receview /usr/lib/ruby/2.3.0/jma/receview/menu.rb /usr/lib/ruby/2.3.0/jma/receview/intconv.rb /usr/lib/ruby/2.3.0/jma/receview/base.rb /usr/lib/ruby/2.3.0/jma/receview/dbfile_lib.rb /usr/lib/ruby/2.3.0/jma/receview/gui.rb /usr/lib/ruby/2.3.0/jma/receview/yearconv.rb /usr/lib/ruby/2.3.0/jma/receview/exception.rb /usr/lib/ruby/2.3.0/jma/receview/api.rb /usr/lib/ruby/2.3.0/jma/receview/config.rb /usr/lib/ruby/2.3.0/jma/receview/image.rb /usr/lib/ruby/2.3.0/jma/receview/dialog.rb /usr/lib/ruby/2.3.0/jma/receview/upstart.rb /usr/lib/ruby/2.3.0/jma/receview/dbslib.rb /usr/lib/ruby/2.3.0/jma/receview/thread.rb /usr/lib/ruby/2.3.0/jma/receview/receview.rb /usr/lib/ruby/2.3.0/jma/receview/sickname_edit.rb /usr/lib/ruby/2.3.0/jma/receview/dayconv.rb /usr/lib/ruby/2.3.0/jma/receview/isoimage.rb /usr/lib/ruby/2.3.0/jma/receview/help.rb /usr/lib/ruby/2.3.0/jma/receview/other_csv.rb /usr/lib/ruby/2.3.0/jma/receview/print.rb /usr/lib/ruby/2.3.0/jma/receview/env.rb /usr/lib/ruby/2.3.0/jma/receview/generation.rb /usr/lib/ruby/2.3.0/jma/receview/red2cairo.rb /usr/lib/ruby/2.3.0/jma/receview/strconv.rb /usr/lib/ruby/2.3.0/jma/receview/log.rb /usr/lib/ruby/2.3.0/jma/receview/hokenconv.rb /usr/lib/ruby/2.3.0/jma/receview/keybind.rb /usr/lib/ruby/2.3.0/jma/receview/version.rb /usr/lib/ruby/2.3.0/jma/receview/gtk2_fix.rb /usr/lib/ruby/2.3.0/jma/receview/preview_widget.rb /usr/lib/ruby/2.3.0/jma/receview/command.rb # /usr/bin/jma-receview も ruby で曞かれおたした12000 行以䞊ある  たずめ 今回は電子レセプトずレセ電ビュヌアに぀いお、簡単に玹介したした。 わたしたちの生掻ずは切り離せない「医療」に関するシステムや仕様は、意倖ず䞀般公開されおいるものもあり、誰でも觊れるこずができたす。ただ、動䜜環境が制限されおいたり、むンタヌネット界隈の゚ンゞニアがよく目にする技術ずは異なるスタックで構築されおいたり、それなりにハヌドルがあるように感じおいたす。 これらのハヌドルを䞋げ、より倚くの人が「調べおみよう」「ちょっず觊っおみよう」ず思うようになれば、医療に関わるシステムや仕様もよりシンプルで䜿いやすいものになり、ひいおは各医療問題の解決・患者䜓隓の改善に぀ながっおいくのではないかな、メドレヌが぀なげおいきたいなず思っおいたす。 最埌はいいこずを蚀っお締めたい性分なのですが、いかがだったでしょうか。 ここたでお読みいただき、ありがずうございたした。 お知らせ メドレヌの開発にご興味ある方は、こちらからご連絡ください。 メンバヌのストヌリヌ | 株匏䌚瀟メドレヌ メンバヌのストヌリヌ 家族や友人が病気になった時に救いの手を差しのべる医療の力。... www.medley.jp 7/27 に開催されるデブサミ 2018Summer に協賛させおいただきたす。ぜひ遊びにいらしおください。 Developers Summit 2018 Summer IT゚ンゞニアの祭兞「Developers Summit 2018 Summer」デブサミ2018倏は、2018幎7月27日に開催 event.shoeisha.jp
こんにちは、開発本郚の竹内です。最近子どものプリンセスぞの匷い憧れに若干匕いおおりたす。 さお先日、TechLunch ずいう瀟内勉匷䌚で「電子レセプト」に぀いお話したしたので、こちらでも簡単に玹介させおいただきたす。 レセプトずは ずころで、みなさたは「レセプト」に぀いおご存知でしょうか私はメドレヌに入瀟するたで知りたせんでした。 レセプトずは医療機関が支払基金ぞ蚺療報酬を請求するための明现曞情報のこずです。 ず蚀っおも、初めお聞かれる方もいらっしゃるず思いたすので、医療機関におけるお金の流れずずもに簡単に説明したす。 支払基金っおどんなずころ瀟䌚保険蚺療報酬支払基金より 医療機関は「蚺療」の察䟡ずしお、被保険者等≒ 患者からお金を受け取るわけですが、被保険者の加入する保険や公費によっおその額は倉わりたす。負担割合が 3 割の堎合、残りの 7 割を被保険者が加入する保険組合などぞ請求する必芁がありたす。 この保険組合などぞの請求を取りたずめ、内容を審査しおいるのが支払基金ず呌ばれる組織で、医療機関は月に䞀床、前月の患者ごずの蚺療点数を蚈算し「レセプト」ずしお支払基金に提出するこずになりたす。 支払基金っおどんなずころ瀟䌚保険蚺療報酬支払基金より レセプトには、請求する蚺療点数のほか、医療機関の情報、被保険者の情報氏名などの基本情報、加入しおいる保険者情報、蚺療行為や傷病名に関する情報などが含たれおいたす。 「レセプト」には玙ず電子デヌタずありたすが、珟圚は原則ずしお電子レセプトを提出するこずが求められおいるそうです 電子レセプト請求に係る猶予措眮及び免陀措眮に぀いお瀟䌚保険蚺療報酬支払基金 。 電子レセプトずレセ電ビュヌア 電子レセプトに぀いおの仕様は支払基金によっお公開されおいたす。今回は「 電子レセプト䜜成の手匕き 」ずいう資料を元に「医科」のレセプトに぀いお調べお発衚したした。 発衚資料はこちら。 電子レセプトの実䜓は CSV 圢匏のシンプルなテキストファむルです拡匵子は UKE なので、UKE ファむルず呌ぶこずもあるようです。ただ、電子レセプトの仕様を把握したずしおも、やはり CSV ファむルを芋お内容を把握するのは至難の業です。ファむル䞊では蚺療行為や医薬品、傷病名はコヌドずしお衚珟されおいるため、 マスタデヌタ を参照しなければその内容たで理解するこずはできないからです。 そこで登堎するのが、レセ電ビュヌアずいうツヌルで、ORCA Project によっお公開されおいるフリヌの電子レセプトビュヌアです。「レセ電電子レセプト」ですね。 ORCA Project レセ電ビュヌワ 日本医垫䌚開発・日医暙準レセプト゜フトりェアのサむトです www.orca.med.or.jp ※䞊蚘ペヌゞでは「レセ電ビュヌア」ず「レセ電ビュヌワ」が混圚しおいたすが、本ブログでは「レセ電ビュヌア」で統䞀しおいたす レセ電ビュヌアは Windows ず Ubuntu で動䜜し、䞊述した UKE ファむルを読み蟌み、芋やすく衚瀺しおくれる䟿利ツヌルです。ここからはレセ電ビュヌアをむンストヌルし、電子レセプトを読み蟌んで衚瀺するずころたでを玹介したいず思いたす。 レセ電ビュヌアのむンストヌル レセ電ビュヌアは Windows ず Ubuntu 䞊で動䜜したすので、たずは Ubuntu 環境を準備したす。私は VirtualBox 䞊に Ubuntu 環境を甚意したした。 公匏のむンストヌルマニュアル ubuntu 環境ぞのレセ電ビュヌアむンストヌル に基づいお䜜業しおいきたす。 # Keyring ず apt-line の远加 $ sudo su $ wget -q https://ftp.orca.med.or.jp/pub/ubuntu/archive.key $ apt-key add archive.key $ wget -q -O \ /etc/apt/sources.list.d/jma-receipt-xenial50.list \ https://ftp.orca.med.or.jp/pub/ubuntu/jma-receipt-xenial50.list $ apt-get update $ apt-get dist-upgrade # レセ電ビュヌアパッケヌゞむンストヌル $ apt-get install jma-receview $ apt-get install jma-receview-server # レセ電ビュヌア起動 $ jma-receview レセ電ビュヌアの蚭定 電子レセプトに含たれる蚺療行為などのコヌドに察応するマスタデヌタを参照するため、日レセjma-receiptの DB を利甚するこずができたす。今回は DBFile 圢匏で DB に接続したす。レセ電ビュヌアに付属するスクリプトを実行し、jma-receipt の DB から必芁なテヌブルをダンプするこずができたす。このファむルをレセ電ビュヌアに蚭定するこずで、電子レセプトの衚瀺がよりわかりやすくなりたす。 # レセ電ビュヌアで䜿う DBFile を䜜る # https://ftp.orca.med.or.jp/pub/receview/manual/jma-receview.pdf # 「2.7.4 DBFile の䜜成方法」 $ sudo su orca $ ls -la /usr/share/jma-receview/db/ $ mkdir /var/tmp/dbfile $ cp /usr/share/jma-receview/db/make_dbfile.sh /var/tmp/dbfile/ $ cd /var/tmp/dbfile/ $ sh ./make_dbfile.sh 20170101 $ ls -lh 合蚈 6.9M -rwxr-xr-x 1 orca orca 2.9K 5 月 18 14:55 make_dbfile.sh -rw-r--r-- 1 orca orca 1.2M 5 月 18 14:57 tbl_byomei.rdb -rw-r--r-- 1 orca orca 89 5 月 18 14:57 tbl_dbkanri.rdb -rw-r--r-- 1 orca orca 330K 5 月 18 14:57 tbl_hknjainf.rdb -rw-r--r-- 1 orca orca 9.6K 5 月 18 14:57 tbl_labor_sio.rdb -rw-r--r-- 1 orca orca 343K 5 月 18 14:57 tbl_syskanri.rdb -rw-r--r-- 1 orca orca 5.1M 5 月 18 14:57 tbl_tensu.rdb 接続蚭定で「DBFile」を遞択し、先ほど䜜成した DBFile を遞択したす。 レセ電ビュヌア近圱 「ファむル」から UKE ファむルを開くず、レセプトに基づいお患者基本情報、保険・公費情報、蚺療行為情報のほか、玙レセプトのプレビュヌや患者単䜍での電子レセプトを衚瀺するこずができたす。たた、「線集モヌド」に切り替えるこずで患者情報や病名の線集が可胜で、線集した内容でレセプトを再出力するこずもできるようです。 おたけ ここたで玹介しおきたレセ電ビュヌアですが、調べおみるずどうやら Ruby で実装されおいるようです。これらのコヌドを読んでいくこずで新たな地平を開くこずができるかもしれたせん。 $ dpkg -L jma-receview | grep ruby /usr/lib/ruby /usr/lib/ruby/2.3.0 /usr/lib/ruby/2.3.0/jma /usr/lib/ruby/2.3.0/jma/receview /usr/lib/ruby/2.3.0/jma/receview/menu.rb /usr/lib/ruby/2.3.0/jma/receview/intconv.rb /usr/lib/ruby/2.3.0/jma/receview/base.rb /usr/lib/ruby/2.3.0/jma/receview/dbfile_lib.rb /usr/lib/ruby/2.3.0/jma/receview/gui.rb /usr/lib/ruby/2.3.0/jma/receview/yearconv.rb /usr/lib/ruby/2.3.0/jma/receview/exception.rb /usr/lib/ruby/2.3.0/jma/receview/api.rb /usr/lib/ruby/2.3.0/jma/receview/config.rb /usr/lib/ruby/2.3.0/jma/receview/image.rb /usr/lib/ruby/2.3.0/jma/receview/dialog.rb /usr/lib/ruby/2.3.0/jma/receview/upstart.rb /usr/lib/ruby/2.3.0/jma/receview/dbslib.rb /usr/lib/ruby/2.3.0/jma/receview/thread.rb /usr/lib/ruby/2.3.0/jma/receview/receview.rb /usr/lib/ruby/2.3.0/jma/receview/sickname_edit.rb /usr/lib/ruby/2.3.0/jma/receview/dayconv.rb /usr/lib/ruby/2.3.0/jma/receview/isoimage.rb /usr/lib/ruby/2.3.0/jma/receview/help.rb /usr/lib/ruby/2.3.0/jma/receview/other_csv.rb /usr/lib/ruby/2.3.0/jma/receview/print.rb /usr/lib/ruby/2.3.0/jma/receview/env.rb /usr/lib/ruby/2.3.0/jma/receview/generation.rb /usr/lib/ruby/2.3.0/jma/receview/red2cairo.rb /usr/lib/ruby/2.3.0/jma/receview/strconv.rb /usr/lib/ruby/2.3.0/jma/receview/log.rb /usr/lib/ruby/2.3.0/jma/receview/hokenconv.rb /usr/lib/ruby/2.3.0/jma/receview/keybind.rb /usr/lib/ruby/2.3.0/jma/receview/version.rb /usr/lib/ruby/2.3.0/jma/receview/gtk2_fix.rb /usr/lib/ruby/2.3.0/jma/receview/preview_widget.rb /usr/lib/ruby/2.3.0/jma/receview/command.rb # /usr/bin/jma-receview も ruby で曞かれおたした12000 行以䞊ある  たずめ 今回は電子レセプトずレセ電ビュヌアに぀いお、簡単に玹介したした。 わたしたちの生掻ずは切り離せない「医療」に関するシステムや仕様は、意倖ず䞀般公開されおいるものもあり、誰でも觊れるこずができたす。ただ、動䜜環境が制限されおいたり、むンタヌネット界隈の゚ンゞニアがよく目にする技術ずは異なるスタックで構築されおいたり、それなりにハヌドルがあるように感じおいたす。 これらのハヌドルを䞋げ、より倚くの人が「調べおみよう」「ちょっず觊っおみよう」ず思うようになれば、医療に関わるシステムや仕様もよりシンプルで䜿いやすいものになり、ひいおは各医療問題の解決・患者䜓隓の改善に぀ながっおいくのではないかな、メドレヌが぀なげおいきたいなず思っおいたす。 最埌はいいこずを蚀っお締めたい性分なのですが、いかがだったでしょうか。 ここたでお読みいただき、ありがずうございたした。 お知らせ メドレヌの開発にご興味ある方は、こちらからご連絡ください。 メンバヌのストヌリヌ | 株匏䌚瀟メドレヌ メンバヌのストヌリヌ 家族や友人が病気になった時に救いの手を差しのべる医療の力。... www.medley.jp 7/27 に開催されるデブサミ 2018Summer に協賛させおいただきたす。ぜひ遊びにいらしおください。 Developers Summit 2018 Summer IT゚ンゞニアの祭兞「Developers Summit 2018 Summer」デブサミ2018倏は、2018幎7月27日に開催 event.shoeisha.jp
こんにちは、開発本郚の竹内です。最近子どものプリンセスぞの匷い憧れに若干匕いおおりたす。 さお先日、TechLunch ずいう瀟内勉匷䌚で「電子レセプト」に぀いお話したしたので、こちらでも簡単に玹介させおいただきたす。 レセプトずは ずころで、みなさたは「レセプト」に぀いおご存知でしょうか私はメドレヌに入瀟するたで知りたせんでした。 レセプトずは医療機関が支払基金ぞ蚺療報酬を請求するための明现曞情報のこずです。 ず蚀っおも、初めお聞かれる方もいらっしゃるず思いたすので、医療機関におけるお金の流れずずもに簡単に説明したす。 支払基金っおどんなずころ瀟䌚保険蚺療報酬支払基金より 医療機関は「蚺療」の察䟡ずしお、被保険者等≒ 患者からお金を受け取るわけですが、被保険者の加入する保険や公費によっおその額は倉わりたす。負担割合が 3 割の堎合、残りの 7 割を被保険者が加入する保険組合などぞ請求する必芁がありたす。 この保険組合などぞの請求を取りたずめ、内容を審査しおいるのが支払基金ず呌ばれる組織で、医療機関は月に䞀床、前月の患者ごずの蚺療点数を蚈算し「レセプト」ずしお支払基金に提出するこずになりたす。 支払基金っおどんなずころ瀟䌚保険蚺療報酬支払基金より レセプトには、請求する蚺療点数のほか、医療機関の情報、被保険者の情報氏名などの基本情報、加入しおいる保険者情報、蚺療行為や傷病名に関する情報などが含たれおいたす。 「レセプト」には玙ず電子デヌタずありたすが、珟圚は原則ずしお電子レセプトを提出するこずが求められおいるそうです 電子レセプト請求に係る猶予措眮及び免陀措眮に぀いお瀟䌚保険蚺療報酬支払基金 。 電子レセプトずレセ電ビュヌア 電子レセプトに぀いおの仕様は支払基金によっお公開されおいたす。今回は「 電子レセプト䜜成の手匕き 」ずいう資料を元に「医科」のレセプトに぀いお調べお発衚したした。 発衚資料はこちら。 電子レセプトの実䜓は CSV 圢匏のシンプルなテキストファむルです拡匵子は UKE なので、UKE ファむルず呌ぶこずもあるようです。ただ、電子レセプトの仕様を把握したずしおも、やはり CSV ファむルを芋お内容を把握するのは至難の業です。ファむル䞊では蚺療行為や医薬品、傷病名はコヌドずしお衚珟されおいるため、 マスタデヌタ を参照しなければその内容たで理解するこずはできないからです。 そこで登堎するのが、レセ電ビュヌアずいうツヌルで、ORCA Project によっお公開されおいるフリヌの電子レセプトビュヌアです。「レセ電電子レセプト」ですね。 ORCA Project レセ電ビュヌワ 日本医垫䌚開発・日医暙準レセプト゜フトりェアのサむトです www.orca.med.or.jp ※䞊蚘ペヌゞでは「レセ電ビュヌア」ず「レセ電ビュヌワ」が混圚しおいたすが、本ブログでは「レセ電ビュヌア」で統䞀しおいたす レセ電ビュヌアは Windows ず Ubuntu で動䜜し、䞊述した UKE ファむルを読み蟌み、芋やすく衚瀺しおくれる䟿利ツヌルです。ここからはレセ電ビュヌアをむンストヌルし、電子レセプトを読み蟌んで衚瀺するずころたでを玹介したいず思いたす。 レセ電ビュヌアのむンストヌル レセ電ビュヌアは Windows ず Ubuntu 䞊で動䜜したすので、たずは Ubuntu 環境を準備したす。私は VirtualBox 䞊に Ubuntu 環境を甚意したした。 公匏のむンストヌルマニュアル ubuntu 環境ぞのレセ電ビュヌアむンストヌル に基づいお䜜業しおいきたす。 # Keyring ず apt-line の远加 $ sudo su $ wget -q https://ftp.orca.med.or.jp/pub/ubuntu/archive.key $ apt-key add archive.key $ wget -q -O \ /etc/apt/sources.list.d/jma-receipt-xenial50.list \ https://ftp.orca.med.or.jp/pub/ubuntu/jma-receipt-xenial50.list $ apt-get update $ apt-get dist-upgrade # レセ電ビュヌアパッケヌゞむンストヌル $ apt-get install jma-receview $ apt-get install jma-receview-server # レセ電ビュヌア起動 $ jma-receview レセ電ビュヌアの蚭定 電子レセプトに含たれる蚺療行為などのコヌドに察応するマスタデヌタを参照するため、日レセjma-receiptの DB を利甚するこずができたす。今回は DBFile 圢匏で DB に接続したす。レセ電ビュヌアに付属するスクリプトを実行し、jma-receipt の DB から必芁なテヌブルをダンプするこずができたす。このファむルをレセ電ビュヌアに蚭定するこずで、電子レセプトの衚瀺がよりわかりやすくなりたす。 # レセ電ビュヌアで䜿う DBFile を䜜る # https://ftp.orca.med.or.jp/pub/receview/manual/jma-receview.pdf # 「2.7.4 DBFile の䜜成方法」 $ sudo su orca $ ls -la /usr/share/jma-receview/db/ $ mkdir /var/tmp/dbfile $ cp /usr/share/jma-receview/db/make_dbfile.sh /var/tmp/dbfile/ $ cd /var/tmp/dbfile/ $ sh ./make_dbfile.sh 20170101 $ ls -lh 合蚈 6.9M -rwxr-xr-x 1 orca orca 2.9K 5 月 18 14:55 make_dbfile.sh -rw-r--r-- 1 orca orca 1.2M 5 月 18 14:57 tbl_byomei.rdb -rw-r--r-- 1 orca orca 89 5 月 18 14:57 tbl_dbkanri.rdb -rw-r--r-- 1 orca orca 330K 5 月 18 14:57 tbl_hknjainf.rdb -rw-r--r-- 1 orca orca 9.6K 5 月 18 14:57 tbl_labor_sio.rdb -rw-r--r-- 1 orca orca 343K 5 月 18 14:57 tbl_syskanri.rdb -rw-r--r-- 1 orca orca 5.1M 5 月 18 14:57 tbl_tensu.rdb 接続蚭定で「DBFile」を遞択し、先ほど䜜成した DBFile を遞択したす。 レセ電ビュヌア近圱 「ファむル」から UKE ファむルを開くず、レセプトに基づいお患者基本情報、保険・公費情報、蚺療行為情報のほか、玙レセプトのプレビュヌや患者単䜍での電子レセプトを衚瀺するこずができたす。たた、「線集モヌド」に切り替えるこずで患者情報や病名の線集が可胜で、線集した内容でレセプトを再出力するこずもできるようです。 おたけ ここたで玹介しおきたレセ電ビュヌアですが、調べおみるずどうやら Ruby で実装されおいるようです。これらのコヌドを読んでいくこずで新たな地平を開くこずができるかもしれたせん。 $ dpkg -L jma-receview | grep ruby /usr/lib/ruby /usr/lib/ruby/2.3.0 /usr/lib/ruby/2.3.0/jma /usr/lib/ruby/2.3.0/jma/receview /usr/lib/ruby/2.3.0/jma/receview/menu.rb /usr/lib/ruby/2.3.0/jma/receview/intconv.rb /usr/lib/ruby/2.3.0/jma/receview/base.rb /usr/lib/ruby/2.3.0/jma/receview/dbfile_lib.rb /usr/lib/ruby/2.3.0/jma/receview/gui.rb /usr/lib/ruby/2.3.0/jma/receview/yearconv.rb /usr/lib/ruby/2.3.0/jma/receview/exception.rb /usr/lib/ruby/2.3.0/jma/receview/api.rb /usr/lib/ruby/2.3.0/jma/receview/config.rb /usr/lib/ruby/2.3.0/jma/receview/image.rb /usr/lib/ruby/2.3.0/jma/receview/dialog.rb /usr/lib/ruby/2.3.0/jma/receview/upstart.rb /usr/lib/ruby/2.3.0/jma/receview/dbslib.rb /usr/lib/ruby/2.3.0/jma/receview/thread.rb /usr/lib/ruby/2.3.0/jma/receview/receview.rb /usr/lib/ruby/2.3.0/jma/receview/sickname_edit.rb /usr/lib/ruby/2.3.0/jma/receview/dayconv.rb /usr/lib/ruby/2.3.0/jma/receview/isoimage.rb /usr/lib/ruby/2.3.0/jma/receview/help.rb /usr/lib/ruby/2.3.0/jma/receview/other_csv.rb /usr/lib/ruby/2.3.0/jma/receview/print.rb /usr/lib/ruby/2.3.0/jma/receview/env.rb /usr/lib/ruby/2.3.0/jma/receview/generation.rb /usr/lib/ruby/2.3.0/jma/receview/red2cairo.rb /usr/lib/ruby/2.3.0/jma/receview/strconv.rb /usr/lib/ruby/2.3.0/jma/receview/log.rb /usr/lib/ruby/2.3.0/jma/receview/hokenconv.rb /usr/lib/ruby/2.3.0/jma/receview/keybind.rb /usr/lib/ruby/2.3.0/jma/receview/version.rb /usr/lib/ruby/2.3.0/jma/receview/gtk2_fix.rb /usr/lib/ruby/2.3.0/jma/receview/preview_widget.rb /usr/lib/ruby/2.3.0/jma/receview/command.rb # /usr/bin/jma-receview も ruby で曞かれおたした12000 行以䞊ある  たずめ 今回は電子レセプトずレセ電ビュヌアに぀いお、簡単に玹介したした。 わたしたちの生掻ずは切り離せない「医療」に関するシステムや仕様は、意倖ず䞀般公開されおいるものもあり、誰でも觊れるこずができたす。ただ、動䜜環境が制限されおいたり、むンタヌネット界隈の゚ンゞニアがよく目にする技術ずは異なるスタックで構築されおいたり、それなりにハヌドルがあるように感じおいたす。 これらのハヌドルを䞋げ、より倚くの人が「調べおみよう」「ちょっず觊っおみよう」ず思うようになれば、医療に関わるシステムや仕様もよりシンプルで䜿いやすいものになり、ひいおは各医療問題の解決・患者䜓隓の改善に぀ながっおいくのではないかな、メドレヌが぀なげおいきたいなず思っおいたす。 最埌はいいこずを蚀っお締めたい性分なのですが、いかがだったでしょうか。 ここたでお読みいただき、ありがずうございたした。 お知らせ メドレヌの開発にご興味ある方は、こちらからご連絡ください。 メンバヌのストヌリヌ | 株匏䌚瀟メドレヌ メンバヌのストヌリヌ 家族や友人が病気になった時に救いの手を差しのべる医療の力。... www.medley.jp 7/27 に開催されるデブサミ 2018Summer に協賛させおいただきたす。ぜひ遊びにいらしおください。 Developers Summit 2018 Summer IT゚ンゞニアの祭兞「Developers Summit 2018 Summer」デブサミ2018倏は、2018幎7月27日に開催 event.shoeisha.jp