none
PowerShell上で"/"(スラッシュ)を含むレジストリキーを作成する

    質問

  • いつもお世話になっております。
    以下、質問をさせていただきます。

    ◆環境:
     Windows Server 2012 R2 Standard
     PowerShell 4.0

    ◆実施したいこと:
     .ps1ファイル上で、Windows ServerのRC4を無効化したい

    ◆経緯:
    SSLを使用するにあたり、セキュリティ対策として以下を無効化しようとしました。
    Triple DES
    SSLv2, SSLv3
    RC4

    複数のサーバーに対して実施する必要があり、個別にレジストリエディターで編集するのは危険と考えて
    .ps1ファイルを作成し、PowerShellから実施することを検討しました。
    上記に対応するレジストリキーはデフォルトでは存在しないため、レジストリキーを作成して値を設定する
    実装を考えていました。

    Triple DES、SSLv2、SSLv3は問題なく実施できたのですが、RC4でエラーが発生しました。
    確認したところ、レジストリキーの作成に失敗していました。
    エラーが発生した箇所とエラーは以下の通りです。

    コード
    ==============================================
    New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 128/128"
    ==============================================

    エラー
    ==============================================
    New-Item : 指定したパスにレジストリ キーが存在しません。
    発生場所 行:1 文字:1
    + New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNE ...
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : InvalidArgument: (HKEY_LOCAL_MACH...Ciphers\RC4 128:String) [New-Item]、ArgumentException
        + FullyQualifiedErrorId : System.ArgumentException,Microsoft.PowerShell.Commands.NewItemCommand
    ==============================================

    エラーの内容から、"/"が"\"と同じく、パスのセパレータとして認識されていると推察しています。
    New-Itemはファイル・フォルダも作成しますので、Windowsの仕様上そのような動きになること自体は
    納得しています。
    上記推察が正しければ、"/"をエスケープしても意味がないと考えています。
    (実際試しましたが失敗しました)
    ただ、Get-Itemは"/"があっても正常に動作しているため自分の推察が的外れかもしれません。

    ◆質問
    PowerShellで、"/"を含むレジストリキーを作成することはできないでしょうか。
    RC4を無効化する更新プログラムがあることは認識しているのですが、可能であれば他の暗号スイートや
    プロトコルとまとめて同一.ps1内で無効化したいと考えています。

    ◆上記調査にあたり参考にしたページ
    https://support.microsoft.com/ja-jp/help/2868725/microsoft-security-advisory-update-for-disabling-rc4
    https://www.tbs-certificates.co.uk/FAQ/en/desactiver_rc4_windows.html
    http://www.atmarkit.co.jp/fwin2k/win2ktips/1030psreg/psreg.html


    何卒よろしくお願いいたします。
    2018年3月16日 6:10

回答

すべての返信

  • これでどうでしょう。

    $key = (Get-Item HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\).OpenSubKey('Ciphers', $true).CreateSubKey('RC4 128/128')
    $key.SetValue('Enabled', 0, 'DWord')

    2018年3月16日 6:30
  • これも駄目ですね。

    New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 128$([char]0x2f)128"

    これなら通りますが、文字が変わってしまう…。

    New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 128$([char]0x2215)128"

    コマンドレットでは無理なようなので、先の投稿のように、.NET のメソッドとして文字列指定する必要がありそうです。

    2018年3月16日 6:48
  • 早速ご回答いただきありがとうございます。

    仰る通り、"[char]0x2f"は私が記載したものと同じエラーが発生し、"[char]0x2215"は別の文字ですのでRC4が無効化されていなそうです。

    先にご提案いただいたCreateSubKeyを使う方であれば実現できそうです。

    ご助力いただきありがとうございました。

    2018年3月16日 7:08
  • 解決済みですし結論は変わりませんが少し調べたので書き留めておきます。

    PowerShellではディレクトリ区切りとして \ 及び / をサポートしています。このことは \ と / の両方が混在した場合に2つ可能性を生みます。例えば "abc\def/ghi" とあった場合に

    1. "abc" \ "def/ghi"
    2. "abc" \ "def" \ "ghi"

    どちらとも解釈できるため、PowerShellでは1.の項目の存在を確認できた場合に限り1.と見なし、そうでない場合は2.と見なします。具体的にはNavigationCmdletProvider.NormalizePathで実装されています。
    こうなると結果は想像できると思いますが、New-Itemによる新規作成だけは存在確認ができないため2.と判断されてしまい、ご質問のようなキー作成はできませんし、Get-Itemは期待した動作をします。

    2018年3月16日 8:06
  • なるほど、なぜNew-Itemはエラーとなり、Get-Itemは動作するのか理解できました。となると、レジストリとしては例に挙げていただいた1、2両者とも作成できると思いますが、1でGet-Itemすると1、2両方とも取得してしまいそうですね(実機が手元にないためすぐ確認できませんが・・・)。個人的には極力レジストリキーには"/"を使わないようにしようと思いました。 調査いただきありがとうございました。
    • 編集済み p1nk5p1der 2018年3月17日 4:59 改行がおかしかったので
    2018年3月17日 4:58