Home > Windows にまつわる e.t.c.

PowerShell で公開鍵方式暗号ファイルを交換をする


暗号化したファイルをメールに添付して、「パスワードは別メールで送ります」といったやりとを見たことはありませんか?

もし、間違った相手に暗号化した機密情報ファイルとパスワードを送ってしまうと重大インシデントになってしまいます。

あるいは、悪意ある第三者が受信者の通信を傍受していれば、暗号化したファイルとパスワードのセットを手に入れることができます。

パスワードを別メールで送るのは、セキュリティ的にあまり意味の無い社会慣習だと言ってもいいでしょう。

この問題を解決するのが「公開鍵方式暗号」なのです。

 

スクリプトの概要

スクリプトの特徴

必要環境

Windows PowerShell の使い方

PowerShell Core を使用する場合

スクリプトのインストール方法

チュートリアル「鍵ペアの作成と、ファイルの暗号化と復号化」

スクリプトの機能

パラメーター

パラメーターの省略

公開鍵の省略形

実行例

ディレクトリ構造

アンインストール方法

FAQ

おまけ(PowerShell の TAB 補完)

使用しているアルゴリズム

更新履歴

リポジトリ

フィードバック

関連情報

 

スクリプトの概要

PowerShell で公開鍵方式暗号/復号をします

Windows、Mac、Linux のマルチプラットフォームで使用できます

 

コマンドラインツールですが、使い方は簡単です。

例えば secret.txt を暗号化して yamada さんに渡す場合は以下のようにします

PS > .\PSCrypto.ps1 .\secret.txt yamada

 

暗号化された secret.enc を受け取った yamada さんが復号化する場合は以下のようにします

PS > .\PSCrypto.ps1 .\secret.enc

 

スクリプトの特徴

良いところ

・復号用のパスワードを送る必要がありません(公開鍵を一度だけ交換)

・指定した相手以外が復号できないので、誤送信による情報漏洩リスクが低減できます

・復号時に電子署名確認が可能なで、なりすましと改ざんを検出する事が出来ます

・PowerShell Core(7 以降)対応しているので、Windows、Mac、Linux のマルチプラットフォームに対応しています

・Windows 環境であれば、Windows 標準機能である Windows PowerShellで実行可能なので、スクリプト以外ののインストールは必要がありません

・スクリプトなので、どんな処理をしているか確認できます

残念なところ

・GUI が無いので PC ビギナーさん向けではないかも...

 

必要環境

Windows PowerShell 5.x(Windows 10 推奨)

PowerShell Core 7 以降(Mac、Linux、Windows)

 

Windows PowerShell の使い方

PowerShell プロンプトを開く

PowerShell プロンプトを開くには、スタートメニューを開いた状態で power と入力すると、「Windows PowerShell」が表示されるので、これを選択します。

 

PowerShell プロンプトを開いたら、タスクバーに表示されてた PowerShell のアイコン を右クリックしてタスクバーにピン止めしておくと良いでしょう。

 

スクリプト実行を許可する

Windows PowerShell ではスクリプトの実行が default で禁止されているので、実行許可をします。

# スクリプト実行が許可されていなければ許可する
if((Get-ExecutionPolicy -Scope LocalMachine) -ne "RemoteSigned"){Set-ExecutionPolicy RemoteSigned -Scope CurrentUser -Force}

 

PowerShell Core を使用する場合

PowerShell Core は以下のページから該当 OS の PowerShell Core を入手しインストールするか、

GitHub - PowerShell/PowerShell: PowerShell for every system!
https://github.com/PowerShell/PowerShell

 

あるいは、以下のページの手順に従ってインストールします

Windows への PowerShell のインストール
https://docs.microsoft.com/ja-jp/powershell/scripting/install/installing-powershell-core-on-windows?WT.mc_id=WD-MVP-36880

Linux への PowerShell のインストール
https://docs.microsoft.com/ja-jp/powershell/scripting/install/installing-powershell-core-on-linux?WT.mc_id=WD-MVP-36880

macOS への PowerShell のインストール
https://docs.microsoft.com/ja-jp/powershell/scripting/install/installing-powershell-core-on-macos?WT.mc_id=WD-MVP-36880

 

PowerShell Core インストール後、ターミナルで「pwsh」と入力すると PowerShell Core が起動します。

Windows 環境であれば、スタートメニュー に PowerShell があります。

PowerShell の起動方法は、OS によって他にも便利な方法があったりするので、別途検索してください(手抜きご容赦)

 

スクリプトのインストール方法

GitHub リポジトリにあるスクリプト(PSCrypto.ps1)を任意のフォルダーにコピーします

URL
https://github.com/MuraAtVwnet/PSCrypto

 

リポジトリ

git@github.com:MuraAtVwnet/PSCrypto.git

https://github.com/MuraAtVwnet/PSCrypto.git

 

リポジトリを Clone せずにスクリプトをプロファイルディレクトリに配置する場合は、PowerShell ウインドウに以下をコピペしてください(マウス右クリックでペースト)

プロファイルディレクトリに PSCrypto\PSCrypto.ps1 がセットされます。

# スクリプトをダウンロードする
$GitPath = "https://raw.githubusercontent.com/MuraAtVwnet/PSCrypto/master/PSCrypto.ps1"
$ScriptPath = "~/"
$ScriptName = "PSCrypto.ps1"
$ScriptFullName = Join-Path $ScriptPath $ScriptName
Invoke-WebRequest $GitPath -Outfile $ScriptFullName

 

チュートリアル「鍵ペアの作成と、ファイルの暗号化と復号化」

通常運用では相手の公開鍵を使ってファイルを暗号化し、相手が自分の秘密鍵を使って復号化するのですが、チュートリアルなので自分の公開鍵で暗号化して、自分の秘密鍵で復号化します。

スクリプトである PSCrypto.ps1 は相対 Path か、絶対 Path のいずれかを指定して実行します。

PowerShell のお約束で、相対 Path の場合は、「./」形式を使用します。
Windows 環境の場合は「.\」で問題ありません。

 

今回のチュートリアルは、以下環境で実行した想定にします

・Windows 10 環境
・「Test-UserA」でログインしている
・Windows PowerShell を使用する
・プロファイルフォルダーに PSCrypto.ps1 を配置した
・プロファイルフォルダーに置いた Test.txt を暗号化する
・暗号化したファイルをプロファイルフォルダーの .\Documet にコピーし復号化する

 

スクリプトディレクトリに移動

プロファイル ディレクトリ以外がカレントになっている場合のみ必要です

cd ~/

 

鍵ペア作成

カレントにある PSCrypto.ps1 を相対指定し、-Mode CreateKey で鍵ペアを作ります

Mac、Linux 環境では秘密鍵のパスワードをセットします

.\PSCrypto.ps1 -Mode CreateKey

 

公開鍵の出力先が表示され、Windows 環境であればエクスプローラーが開き公開鍵が表示されます。

 

暗号化

スクリプトディレクトリに Test.txt 作成し、自分の公開鍵を指定して暗号化します。

適当なファイルをスクリプトディレクトリにコピーして暗号化しても構いません。

.\PSCrypto.ps1 -Mode Encrypto -Path .\Test.txt -PublicKeys Test-UserA

 

暗号化したファイルと同じディレクトリに暗号化された Test.enc が出力されます

 

復号化

相手に暗号化ファイルを渡した想定で、プロファイルディレクトリの .\Docunets に Test.enc をコピーし、自分の秘密鍵で復号化します。

copy .\Test.enc .\Documents\
.\PSCrypto.ps1 -Mode Decrypto -Path .\Documents\Test.enc

 

プロファイルディレクトリの .\Documents に Test.txt が復号されます。

中身を見て復号されているか確かめてください。

 

スクリプトの機能

暗号化(-Mode Encrypto)

相手の公開鍵を -PublicKeys で指定してファイルを暗号化します

公開鍵で指定した相手以外は復号できないので、誤送によるリスクが大幅低減します

自分の秘密鍵で電子署名するので、改ざん/なりすまし検出が可能です

Mac、Linux 環境では、秘密鍵のパスワードの入力が必要です

復号化(-Mode Decrypto)

自分の秘密鍵を使って復号化します

ファイル送信者公開鍵を -PublicKeys で指定すると、電子署名を確認するので、なりすましや改ざん検出が可能です

Mac、Linux 環境では、秘密鍵のパスワードの入力が必要です

鍵ペア作成(-Mode CreateKey)

公開鍵と秘密鍵のセットを作成します

作成した公開鍵を相手に渡します

相手にも鍵ペアを作成してもらい、相手の公開鍵を入手します

Windows 環境では、キーコンテナを削除しない限り同じ公開鍵が出力されます

Mac、Linux 環境では、新たに鍵ペアを作成します(上書き確認有)

Mac、Linux 環境では、秘密鍵にパスワードを設定ます

秘密鍵パスワードテスト(-Mode TestPrivateKey)

Mac、Linux 環境専用オプション

秘密鍵のパスワードが正しいかの確認をします

秘密鍵の削除(-Mode RemoveKey)

Windows 環境専用オプション

秘密鍵(キーコンテナ)を削除します

キーコンテナのエクスポート(-Mode Export)

Windows 環境専用オプション

秘密鍵(キーコンテナ)をエクスポート(バックアップ)します

キーコンテナエクスポートテスト(-Mode Test)

Windows 環境専用オプション

エクスポートしたファイルがパスワードで復号できるかをテストします

キーコンテナのインポート(-Mode Import)

Windows 環境専用オプション

エクスポートしたファイルから秘密鍵(キーコンテナ)をインポート(リストア)します

 

引数なしでスクリプトを実行するとヘルプが表示されます

 

パラメーター

-Path <String>

暗号/復号するファイルの Path

絶対 Path、相対 Path のいずれでも指定できます

-PublicKeys <String[]>

公開鍵指定

複数指定する場合はカンマで区切ります

-Mode <String>

操作モード

鍵ペア作成: CreateKey
秘密鍵テスト: TestPrivateKey
秘密鍵削除: RemoveKey
暗号化: Encrypto
復号化: Decrypto
Export: Export
Import: Import
Test: Test

-Outfile <String>

出力ファイル(省略可)

 

パラメーターの省略

暗号/復号の時は -Mode 指定と、-Path、 -PublicKeys のオプション名指定を省略できます(Mode はファイルの拡張子で判断)

暗号

PS > .\PSCrypto.ps1 暗号化するファイル 受信者の公開鍵

復号

PS > .\PSCrypto.ps1 復号化するファイル [送信者の公開鍵]

(送信者の公開鍵を省略すると、署名チェックをしません)

 

公開鍵の省略形

公開鍵をデフォルトフォルダ(スクリプトフォルダ\PSScript_PublicKeys)に格納している場合は、公開鍵のフォルダ名(PSScript_PublicKeys)、拡張子(.xml)、サフィックス(_PublicKey)が省略可能です

PSScript_PublicKeys\userA_PublicKey.xml → userA

 

省略形を使わずに公開鍵を指定する場合

PS >.\PSCrypto.ps1 暗号化するファイル .\PSScript_PublicKeys\userA_PublicKey.xml

公開鍵を省略形で指定する場合

PS >.\PSCrypto.ps1 暗号化するファイル userA

複数相手に対して暗号化する場合は、-PublicKeys オプションを明示的に指定し、公開鍵をカンマで区切って下さい

PS > .\PSCrypto.ps1 暗号化するファイル -PublicKeys UserA, UserB

 

実行例

--------------------------

鍵ペアの作成

PS >.\PSCrypto.ps1 -Mode CreateKey

スクリプトフォルダーのサブフォルダ(PSCrypto_PublicKeys)が作成され、公開鍵(UserName_Publickey.xml)が出力されます
Windows 環境では、キーコンテナを削除しない限り同じ公開鍵が出力されます
Mac、Linux 環境では、サブフォルダ(PSCrypto_PrivateKeys)が作成され、秘密鍵鍵(UserName_Privatekey.key)が出力されます

ローカルに出力された鍵のファイル名は変更しないでください(スクリプトが処理内で参照しています)
相手に渡す公開鍵のファイル名を変更したい場合は、別途公開鍵をコピーし、ファイル名変更してください

--------------------------

指定ファイルを暗号化します

PS >.\PSCrypto.ps1 -Mode Encrypto -PublicKeys .\PublicKey\UserName_Publickey.xml -Path C:\Data\SecretData.zip

-PublicKeys に相手の公開鍵を指定します
複数相手に対して暗号化する場合は、公開鍵をカンマで区切って下さい

暗号化する元ファイルと同一フォルダーに暗号化ファイル(.enc)が出力されます
-Outfile を指定すると暗号化ファイルのフルパスが指定できます

Mac、Linux 環境では、秘密鍵のパスワード入力が必要です

--------------------------

省略形で指定ファイルを暗号化します

PS >.\PSCrypto.ps1 C:\Data\SecretData.zip UserName

既定のフォルダ(スクリプトフォルダーの PublicKeys)に公開鍵を置いている場合は、公開鍵の Path と _Publickey.xml を省略
し、相手の UserName だけで公開鍵を指定することが出来ます

複数相手に対して暗号化する場合は、-PublicKeys オプションを明示的に指定し、公開鍵をカンマで区切って下さい

PS > .\PSCrypto.ps1 C:\Data\SecretData.zip -PublicKeys UserA, UserB

--------------------------

暗号化されたファイルを復号化します

PS >.\PSCrypto.ps1 -Mode Decrypto -Path C:\Data\SecretData.enc

暗号化ファイルと同一フォルダーに元ファイル名で復号化されます
-Outfile を指定すると復号化ファイルの出力先フルパスが指定できます

Mac、Linux 環境では、秘密鍵のパスワード入力が必要です

--------------------------

省略形で暗号化されたファイルを復号化します

PS >.\PSCrypto.ps1 C:\Data\SecretData.enc

--------------------------

暗号化されたファイルを復号化し、電子署名を検証します

PS >.\PSCrypto.ps1 -Mode Decrypto -PublicKeys .\PublicKey\UserName_Publickey.xml -Path C:\Data\SecretData.enc

-PublicKeys に送信者の公開鍵を指定し、電子署名を確認します

暗号化ファイルと同一フォルダーに元ファイル名で復号化されます
-Outfile を指定すると復号化されたファイルの出力先フルパスが指定できます

Mac、Linux 環境では、秘密鍵のパスワード入力が必要です

--------------------------

省略形で暗号化されたファイルを復号化し、電子署名を検証します

PS >.\PSCrypto.ps1 C:\Data\SecretData.enc UserName

既定のフォルダ(スクリプトフォルダーの PublicKeys)に公開鍵を置いている場合は、公開鍵の Path と _Publickey.xml を省略し、相手の UserName だけで公開鍵を指定することが出来ます

その他の実行例は PSCrypto.ps1 を引数なしで実行してヘルプを表示するか、以下を見てください。

https://raw.githubusercontent.com/MuraAtVwnet/PSCrypto/master/Readme.txt

 

ディレクトリ構造

スクリプトは以下ディレクトリ構造を使用します
(サブディレクトリは自動作成)

スクリプト

スクリプトディレクトリ\PSCrypto.ps1

公開鍵

スクリプトディレクトリ\PSScript_PublicKeys

秘密鍵(Mac、Linux)

スクリプトディレクトリ\PSScript_PrivateKeys

キーコンテナのエクスポート先(Windows)

スクリプトディレクトリ\PSScript_Export\UserName

 

アンインストール方法

Windows 環境で鍵ペアを作成したのなら、-Mode RemoveKey を実行し、キーコンテナを削除します
(作成した秘密鍵を継続して使用するのであれば、削除前にエクスポートしておきます)

スクリプトと鍵を削除します

 

FAQ

公開鍵方式ってなに?

公開鍵と秘密鍵の鍵ペアを使用した暗号/復号の仕組みです

公開鍵で暗号化したデーターは、秘密鍵でしか復号できません

データーを受け取る人の公開鍵で暗号化すると、秘密鍵を持っている受取人以外が復号することができなくなります

復号のためのパスワードを送る必要もありませんし、目的の相手以外が復号できないので安全なデーター授受がてきます

電子署名ってなに?

送信者が送ったデーターであることを確認する仕組みです

公開鍵方式のもう一つの特徴は、秘密鍵で暗号化したデーターは公開鍵でしか復号できない特徴があります

送信者が自分の秘密鍵でデーターを暗号化し、そのデーターを送信者の公開鍵で復号出来れば、データーを送信者が暗号化した証明になります

この仕組みを使って間違いなく本人が送ったデーターであることを証明するのが電子署名です

実際の処理は、データーをハッシュと呼ばれる処理で小さなサイズの値にして、この値を秘密鍵で暗号化して電子署名として使用します

公開鍵のファイル名変更しても大丈夫?

はい

公開鍵は中身が大切なので、ファイル名を変更しても問題ありません

ローカルに出力された鍵のファイル名は変更しないでください(スクリプトが処理内で参照しています)

相手に渡す公開鍵のファイル名を変更したい場合は、別途公開鍵をコピーし、ファイル名変更してください

公開鍵が漏えいしても大丈夫なの?

公開鍵はその名の通り公開されるものなので、漏えいしても問題ありません
公開鍵から秘密鍵を推測することは数学的にできないようになっています

秘密鍵が漏えいするとどうなるの?

秘密鍵が漏えいすると、第三者が復号できる事になるので暗号運用が破たんします

万が一秘密鍵が漏えいした場合は、Windows 環境はキーコンテナーを削除し、鍵ペアを再作成してください

Mac、Linux 環境は鍵ペアを再作成し現在の鍵を上書きしてください

今まで使っていた公開鍵は使えなくなる(古い公開鍵で暗号化されると復号できない)ので、新しい公開鍵を再配布する必要があります

Windows 秘密鍵を保管しているキーコンテナーのバックアップであるExportは、Exportデーターをパスワードで暗号化しています

暗号化されているとはいえ秘密鍵を持っているのでExportファイルは安全なところに保管してください

コードが見えちゃっているけど安全なの? 暗号アルゴリズムを公開しているけど安全なの?

使用しているアルゴリズムは、強力な暗号として認定されているアルゴリズムです

この認定は、多くの暗号学者による暗号アルゴリズムが攻撃に耐えて、鍵を探り当てる以外の方法で復号出来なかった事実が前提条件になっています

使用している暗号鍵の長さは 256 ビット(1.15x10の77乗)なので、毎秒1億の鍵を試すことができる性能を持ったコンピューターで総当たり解析をした場合に 5x10の67乗秒(1.6x10の60乗年)かかる計算になるので、現実的な復号は不可能なので安全です

公開鍵方式にリスクは無いの?

正しい公開鍵を持っている場合は安全ですが、攻撃者が違う公開鍵を渡すリスクを回避できません

例えば、攻撃者 C が B さんのふりをして、C の公開鍵を A さんに渡した場合です

A さんは B さんに送るつもりで C の公開鍵で暗号化してしまうので、攻撃者である C は自分の秘密鍵を使って B さん宛てのデーターを復号できます(B さんは復号できない)

C は何らかの方法で B さん宛ての通信を傍受すればほしいデーターが手に入ります

この攻撃が成功するケースは多くはないのですが、リスクが無いわけではありません

リスクゼロではないのですが、パスワードを別メールとかで送るよりははるかに安全です(これを担保するのがこのシステムの目的)

運用開始前に、お互いの暗号データーが復号できるかの確認をするのが良いでしょう

(このリスクは、公的 X.509 証明書を使えば回避できますが、仕組みと運用が厄介になるので実装しません)

 

おまけ(PowerShell の TAB 補完)

PowerShell は TAB 補完できるので、ファイル名やオプションの一部を入力して TAB を入力すると、残りが補完されるので入力が楽です

どんなオプションが使えるのかは、- を入れて TAB 補完すると使用可能なオプションが次々と表示されます全て表示し終わると最初に戻ります

PS > .\PSCrypto.ps1 -[TAB]
PS > .\PSCrypto.ps1 -Mode
PS > .\PSCrypto.ps1 -PublicKeys
PS > .\PSCrypto.ps1 -Path
PS > .\PSCrypto.ps1 -Outfile
PS > .\PSCrypto.ps1 -Mode

 

-Mode の入力値も TAB 保管できます

PS > .\PSCrypto.ps1 -Mode [TAB]
PS > .\PSCrypto.ps1 -Mode CreateKey
PS > .\PSCrypto.ps1 -Mode Encrypto
PS > .\PSCrypto.ps1 -Mode Decrypto
PS > .\PSCrypto.ps1 -Mode Export
PS > .\PSCrypto.ps1 -Mode Import
PS > .\PSCrypto.ps1 -Mode RemoveKey
PS > .\PSCrypto.ps1 -Mode Test
PS > .\PSCrypto.ps1 -Mode TestPrivateKey

 

ファイル名、ディレクトリ名も補完できます

PS > .\pscr[TAB]
PS > .\PSCrypto.ps1

PS > .\PSCrypto.ps1 -Mode Encrypto -Path .\tes[TAB]
PS > .\PSCrypto.ps1 -Mode Encrypto -Path .\Test.txt

PS > copy .\Test.txt .\doc[TAB]
PS > copy .\Test.txt .\Documents\

 

使用しているアルゴリズム

暗号/復号/ハッシュ

RSA 公開鍵暗号
AES 256
SHA 256

電子署名

RSA 電子証明(SHA256)

 

更新履歴

0.10 2016/06/01 プロトタイプ完成
0.20 2016/06/05 Beta 1
0.30 2016/06/09 RC 1
0.31 2016/06/12 RC 2
2.00 2017/12/27 処理効率化と暗号データフォーマット変更
2.01 2017/12/29 細々と改良/エクスポートフォルダ場所変更
2.02 2017/12/31 Export/Import/Test フォルダを任意指定できるようにした
2.10 2020/10/15 Mac、Linux サポート(その他チューニング)

 

リポジトリ

以下リポジトリで開発していますので、必要に応じて Clone してください

URL

https://github.com/MuraAtVwnet/PSCrypto

リポジトリ

git@github.com:MuraAtVwnet/PSCrypto.git
https://github.com/MuraAtVwnet/PSCrypto.git

 

フィードバック

フィードバックは、こちらにメールでお願いします。

mura+PSCrypto@vwnet.jp

 

関連情報

AES 256 の PowerShell 実装
http://www.vwnet.jp/Windows/PowerShell/AES.htm

PowerShell で指定サイズのランダムな文字列/バイナリ列を生成する
http://www.vwnet.jp/Windows/PowerShell/CreateRandomData.htm

SHA-2(SHA256) の PowerShell 実装
http://www.vwnet.jp/Windows/PowerShell/SHA256.htm

RSA 公開鍵暗号の PowerShell 実装
http://www.vwnet.jp/Windows/PowerShell/RSACrypto.htm

RSA 電子署名(SHA256)の PowerShell 実装
http://www.vwnet.jp/Windows/PowerShell/RSASignature.htm

PowerShell スクリプト引数(Param)の Tips
http://www.vwnet.jp/Windows/PowerShell/Param.htm

 

 

back.gif (1980 バイト)

home.gif (1907 バイト)

Copyright © MURA All rights reserved.