Lazy Diary @ Hatena Blog

PowerShell / Java / miscellaneous things about software development, Tips & Gochas. CC BY-SA 4.0/Apache License 2.0

cmd.exeとPowerShellの起動速度

体感ではPowerShellの起動速度はcmd.exeと比べて明らかに遅いけれど、具体的にどの程度遅いのか確かめてみた。 OSはWindows 10 version 2004、CPUはIntel(R) Core(TM) i7-8750H CPU @ 2.20GHz(6コア12スレッド)です。 なお、処理に使うウィンドウはPowerShellのものでもcmd.exeのものでも起動速度は変わりませんでした。

# 起動元 起動先 起動回数[回/秒] コマンド
1 cmd.exe cmd.exe 82~84 FOR /L %n IN (1,1,300) DO cmd /V:ON /C "echo !TIME!"
2 cmd.exe powershell.exe 4~5 FOR /L %n IN (1,1,300) DO cmd /V:ON /C powershell.exe -c "Get-Date -Format 'yyyy/MM/dd hh:mm:ss.fff'"
3 powershell.exe cmd.exe 75~77 1..300 | ForEach-Object { cmd /V:ON /C "echo !TIME!" }
4 powershell.exe powershell.exe 4~5 1..300 | ForEach-Object { powershell.exe -c "Get-Date -Format 'yyyy/MM/dd hh:mm:ss.fff'" }

ファイルをAESで暗号化したときに送信先とnonceを共有する方法

AESをECBモードで使っていたり、IVとして固定値を使っていたりするケースを避けるお手本として

  • あるファイルをAESで暗号化し、ローカルマシンのストレージ上に保存しておく
  • 暗号化したファイルをリモートマシンへ送付し、リモートマシンのストレージに保存する
  • あるタイミングでリモートマシン上でファイルを復号する

という処理を実装しようとしたときに、AESで使うIVとかnonceをどう生成し、ローカルマシンとリモートマシンでどう共有するか?という話をまとめておく。なお、以降では話を簡単にするためAESはCTRモードで使用する(nonceを使う)ものとする。nonceは再利用を避けられればそれでよい。nonceの値は推測可能でもよい *1

nonceの生成方法

NIST SP 800-38A *2 では、nonceおよびIVの作成方法として以下の(A)(B)2つの方法が挙げられている。またRFC 5297 *3 ではnonceとしてカウンタを使う方法の他に、タイムスタンプを使う方法(C)が提示されている。

  • (A) カウンタを暗号化する*4
  • (B) FIPS 140-2準拠の乱数を使う
  • (C) タイムスタンプを使う

まず、nonceの生成のためにカウンタを保存する方法(A)は実装や管理の煩雑さから避けたい。末番を保存しておいてそれをカウントアップする方法は、どこに末番を保存するか?末番の採番を並列化可能にするにはどうするか?といった検討が必要になってしまう*5

方法(B)と(C)に大きな違いはないが、(B)には誕生日のパラドックスに起因してnonceの衝突確立が(C)より高いという問題がある。また、完全に重複を避けるには使った乱数をすべて保存しておく必要がある。そのため、ここではいったん(B)を除外する。

ここでは(C)を利用することにする。たとえばシステムクロックのミリ秒までの値をnonceとして利用する。Java 9以降であれば、Instant.now()でシステムクロックを取得すれば、getEpochSecond()とgetNano()でナノ秒単位の時刻が取得できる。システムクロックは一方向にしか進まないため、ある時点でnonceの生成処理が複数同時に実行されることさえ防げば、nonceが再利用されないことを担保できる。

nonceの共有方法

ファイルの復号のため、nonceはローカルマシンとリモートマシンとで共有する必要がある。ここで、ファイルをリモートマシンへ送付する際、nonceを別ファイルに格納して送るのは必要な処理が増えるし、処理の原子性の考慮が難しくなるため避けたい。

ローカルマシンとリモートマシンのシステムクロックの値をnonceとして利用することで、ローカルマシンからリモートマシンへnonceを送信せずにnonceを共有できるのでは?とも考えたけど、暗号化するタイミングと復号するタイミングは異なるはずなので、そもそもこの方法は使えない。仮に使えたとしても、どうしてもローカルマシンとリモートマシンとでnonceの値がズレるタイミングが発生する *6 。また、同時刻に実行された処理で同一のnonceが使われるのを防ぐことも難しい。

nonceはファイルごとに決める必要があり、またファイル間でnonceの値は異なっている必要がある。これはファイル名の特性と同じである *7。そのため、ファイル名にnonceの値を含めて送信することで、ローカルマシンとリモートマシンとでnonceを共有することができる。

nonceの一意性を担保する方法

nonceを生成して暗号化されたファイルを作る際、もしnonceと同じ名前のファイルがすでに存在していたら、そのnonceは使用済ということになる。その場合は再度nonceを取得すればよい。

*1:暗号強度は鍵のビット長で担保される

*2:https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf

*3:https://tools.ietf.org/html/rfc5297

*4:カウンタが暗号ブロック長より短かければECBモードで暗号化しても問題にならない

*5:テストの再現性の面では利点もあるが、それはnonceの生成処理をinject可能にしておけばよい話で、カウンタが必須なわけではない

*6:たとえばYYYYMMDDHHMMSSをnonceにするとして、ローカルマシンの時刻が2020/01/01 01:01:01.999、リモートマシンの時刻が2020/01/01 01:01:02.001とすると、NTPによる時刻同期の精度としては上出来だがnonceとしてはローカルマシンとリモートマシンでズレてしまっているので役に立たないことになる

*7:ファイル名はファイルごとに決める必要があり、同名のファイルは保存できない

「解決済みの質問を削除する」風習の調査(があったらいいな)

Web上のQ&Aサイトでは、質問をした後、回答が得られて問題が解決したら、質問者が質問を削除してしまうというケースが見受けられる。 特に技術的なQ&Aサイトの場合は、同じ疑問を持ったり、同じ問題にぶつかった人が解決方法にたどりつく機会が減ってしまうため、解決済みの質問を削除してしまうのは問題があると言える。たとえばteratailでは、質問者が質問を直接削除するのではなく、削除を「リクエストする」仕組みになっている。また投稿の削除ポリシー *1 で「解決済みの質問についている回答を消すことは、同じ疑問をもつ人たちから知識を奪うことになる」として、解決済みの質問に対しては削除リクエストも原則として行えないようにしている。

teratailのように、「回答が得られた質問を削除する」という行為は日本語のサイトでしばしば見られる。一方で、英語を主な言語とするStack Exchange(英語版Stack Overflowなど)では、回答がついた質問を投稿者自身が直接削除できる。ただし、承認された回答がある場合は削除できないなど、削除にある程度の制限をかけている *2 。Stack Exchangeでは、質問の内容が簡単な場合に、質問に対して回答でなくコメントを投稿することで答えを示しているケースが散見される。これは、この削除の制限への抵触を回避するという目的との関連が示唆される。

  • 解決済みの質問を削除する、という行為は特定の文化圏(地理的な文化圏、および専門分野による文化圏)に特有の事象なのだろうか?
  • 質問者が質問を削除するのはどういった動機によるのだろうか?
    • 質問者の勘違いが原因だったので恥ずかしいから?
    • 質問の内容が簡単すぎて、こんな質問をしていたということを残すのが恥ずかしいから?
    • 質問の対象になったソフトウェアやサービスなどに問題があるように見えるので、ソフトウェアの開発元やサービスの提供元に迷惑だから?
    • ソフトウェアやサービスについて議論が起こっているように見えるので、ソフトウェアの開発元やサービスの提供元に迷惑だから?
    • 議論が起こっているように見えるので、議論を起こしている人だという記録が残るのはいやだから?
    • 自分が質問した内容やもらった回答の内容に対して責任が持てないので、責任を持てないような内容を残すのは無責任でよくないから?
    • 自分の名前が記録に残るのがいやだから?

また、解決済みの質問を削除する行為は、どのような方法で予防できるのだろうか?こういった問題に対して調査・分析を行った論文はあるのだろうか?

非機能要件の安全率の事例収集

非機能要件の安全率として「どのくらいの安全率なら適切か」という値はありません *1 (研究もないように思います)。IPA 非機能要求グレード *2 の「04_項目一覧.pdf」では、性能目標値の「余裕率」として、1倍・1.2倍・1.5倍・2倍・3倍・10倍以上から選択するようになっています。Qiitaの記事*3にあるように、一般的なシステムでは1.2~1.5というのが感覚値ではありますが、これといった根拠はありません。

そこで、政府機関・自治体・各種団体・企業などで使われているシステムの安全率がどの程度か、事例を収集してみることにしました。

# 主管元 名前 安全率 URL
1 厚生労働省 オンライン資格確認システム 1.5 https://www.mhlw.go.jp/file/06-Seisakujouhou-12400000-Hokenkyoku/0000182053.pdf#page=78
2 厚生労働省 年金業務システム 1.2 https://www.mhlw.go.jp/sinsei/chotatu/chotatu/pdf/ikenshousei140806-01.pdf#page=19
3 厚生労働省 間接業務システム 1.3 https://www.mhlw.go.jp/sinsei/chotatu/chotatu/shiyousho-an/dl/090205-1b.pdf#page=3
4 内閣官房 接触確認アプリ 1.2 https://cio.go.jp/sites/default/files/uploads/documents/techteam_20200526_01.pdf#page=24
5 国土交通省 建設キャリアアップシステム 1.2 https://www.mlit.go.jp/common/001156807.pdf#page=364
6 電力広域的運営推進機関 OAシステム 1.5 https://www.occto.or.jp/soukaihoka/rijikai/2019/files/rijikai_236_gijiroku_1.pdf#page=147
7 環境省自然環境局生物多様性センター 巨樹・巨木林データベースシステム 1 http://www.biodic.go.jp/chousa/koukoku29/koukoku29_14_1.pdf#page=78
8 日立製作所 Hitachi System Information Capture 1.2 http://itdoc.hitachi.co.jp/manuals/3021/3021373200/H0373200.PDF#page=478 *4
9 ManageEngine EventLog Analyzer 1.3 https://www.manageengine.jp/products/EventLog_Analyzer/system-requirements.html *5
10 富士通 Interstage Business Application Server 1.25 https://software.fujitsu.com/jp/manual/manualfiles/M090098/J2X16030/08Z200/J6030-02-05-02-03.html *6
11 富士通 Interstage Business Application Server 1.5 https://software.fujitsu.com/jp/manual/manualfiles/M100002/J2UZ9110/02Z2C/irepad/irep0223.htm *7
12 富士通 Symfoware Server 1.5 https://software.fujitsu.com/jp/manual/manualfiles/m120023/j2ul1593/04z200/j1593-i-09-00.html *8
13 富士通 Symfoware Server 1.3 https://software.fujitsu.com/jp/manual/manualfiles/M100005/B1WS0831/01Z200/B0831-e-03-00.html *9
14 富士通 Interstage Shunsaku Data Manager 1.3 https://software.fujitsu.com/jp/manual/manualfiles/M060057/J2X11941/01Z202/usersad/users186.html *10
15 総務省 地域イントラネット基盤施設整備事業 2.0-4.0 https://www.soumu.go.jp/soutsu/kyushu/ai/pdf/intra_manual_H21.pdf

*1:https://www.slideshare.net/natsumet/ss-52426933

*2:https://www.ipa.go.jp/sec/softwareengineering/std/ent03-b.html

*3:https://qiita.com/hot_study_man/items/43de9839a07dd6140937

*4:製品マニュアルで、システムではない

*5:製品マニュアルで、システムではない

*6:製品マニュアルで、システムではない

*7:製品マニュアルで、システムではない

*8:製品マニュアルで、システムではない

*9:製品マニュアルで、システムではない

*10:製品マニュアルで、システムではない

How to add a JMS queue corresponding to jboss.naming.context.java.jboss.resources.xxx.yyy.zzz with jboss-cli

Context

  • You are building a Java web application with JMS.
  • You have added a reference to JMS queue with <res-ref-name>xxx/yyy/zzz</res-ref-name> in web.xml.
  • You have changed the configuration file from standalone.xml to standalone-full.xml to use JMS module.
  • You have added a JMS queue with jboss-cli.
  • Now you are going to deploy the application to Wildfly with ActiveMQ.

Problem

  • You will get the WFLYCTL0412 or WFLYCTL0180 error when you deploy the application. It says that you could not find jboss.naming.context.java.jboss.resources.xxx.yyy.zzz.
  • The error will be not resolved when you add a JMS queue with following command in jboss-cli:
jms-queue add --queue-address=xxx.yyy.zzz --entries=xxx/yyy/zzz
  • You will get another error when you try to add a JMS queue java:comp/env/xxx/yyy/zzz with following command in jboss-cli:
jms-queue add --queue-address=xxx.yyy.zzz --entries=java:comp/env/xxx/yyy/zzz

Reason

  • jboss.naming.context.java.jboss.resources.xxx.yyy.zzz in the error message correspond to a JNDI name java:jboss/resources/xxx/yyy/zzz.
  • java:comp/env/ is ENC (Environment Naming Context). It is a naming convention to refer JNDI resources from web application. You cannot use ENC in application server settings (it does not tied to specific web application).

Solution

You can add a JMS queue corresponding to jboss.naming.context.java.jboss.resources.xxx.yyy.zzz with the following command in jboss-cli:

jms-queue add --queue-address=xxx.yyy.zzz --entries=java:jboss/resources/xxx/yyy/zzz

Note that xxx.yyy.zzz in --queue-address option is an arbitrary name of JMS queue. You can see this name in the result of /subsystem=naming:jndi-view.