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

RSA 公開鍵暗号の PowerShell 実装


.NET で RSA がサポートされているので、PowerShell での RSA 公開鍵暗号/復号実装サンプル書いてみました

公開鍵/秘密鍵をそのまま使う場合の実装

### 鍵の作成
# アセンブリロード
Add-Type -AssemblyName System.Security

# RSACryptoServiceProviderオブジェクト作成
$RSA = New-Object System.Security.Cryptography.RSACryptoServiceProvider

# 公開鍵
$PublicKey = $RSA.ToXmlString($False)

# 秘密鍵
$PrivateKey = $RSA.ToXmlString($True)

 

##################################################
# 公開鍵 暗号化
##################################################
function RSAEncrypto($PublicKey, $PlainString){
    # アセンブリロード
    Add-Type -AssemblyName System.Security

    # バイト配列にする
    $ByteData = [System.Text.Encoding]::UTF8.GetBytes($PlainString)

    # RSACryptoServiceProviderオブジェクト作成
    $RSA = New-Object System.Security.Cryptography.RSACryptoServiceProvider

    # 公開鍵を指定
    $RSA.FromXmlString($PublicKey)

    # 暗号化
    $EncryptedData = $RSA.Encrypt($ByteData, $False)

    # 文字列にする
    $EncryptedString = [System.Convert]::ToBase64String($EncryptedData)

    # オブジェクト削除
    $RSA.Dispose()

    return $EncryptedString
}

 

##################################################
# 秘密鍵 復号化
##################################################
function RSADecrypto($PlivateKey, $EncryptoString){
    # アセンブリロード
    Add-Type -AssemblyName System.Security

    # バイト配列にする
    $ByteData = [System.Convert]::FromBase64String($EncryptoString)

    # RSACryptoServiceProviderオブジェクト作成
    $RSA = New-Object System.Security.Cryptography.RSACryptoServiceProvider

    # 秘密鍵を指定
    $RSA.FromXmlString($PlivateKey)

    # 復号
    $DecryptedData = $RSA.Decrypt($ByteData, $False)

    # 文字列にする
    $PlainString = [System.Text.Encoding]::UTF8.GetString($DecryptedData)

    # オブジェクト削除
    $RSA.Dispose()

    return $PlainString
}

 

秘密鍵をCSP キーコンテナに保存する場合の実装

秘密鍵が漏えいすると困るので、RSAでは秘密鍵をCSP キーコンテナに保存する事が出来ます。

キーコンテナは、ユーザーストアとマシンストアの2種類があります。
ユーザーストアを使用するとログインユーザーごとにユニークなキーコンテナが使用されるので、秘密鍵を持ったユーザー以外での復号が出来なくなります

##################################################
#  鍵を作成し CSP キーコンテナに保存
##################################################
function RSACreateKeyCSP($ContainerName){
    # アセンブリロード
    Add-Type -AssemblyName System.Security

    # CspParameters オブジェクト作成
    $CSPParam = New-Object System.Security.Cryptography.CspParameters

    # マシンストアを使用する(デフォルトはユーザーストア。これを有効にするとマシンストアが使用される)
    # $CSPParam.Flags = [System.Security.Cryptography.CspProviderFlags]::UseMachineKeyStore

    # CSP キーコンテナ名
    $CSPParam.KeyContainerName = $ContainerName

    # RSACryptoServiceProviderオブジェクト作成し秘密鍵を格納
    $RSA = New-Object System.Security.Cryptography.RSACryptoServiceProvider($CSPParam)

    # 公開鍵
    $PublicKey = $RSA.ToXmlString($False)

    # オブジェクト削除
    $RSA.Dispose()

    return $PublicKey
}

CSP キーコンテナを削除しない限り、同一 CSP キーコンテナ名を指定すると、同じ公開鍵が取得できます。
このため、公開鍵を紛失した場合は RSACreateKeyCSP で公開鍵を再発行することができます。

 

(暗号化は「公開鍵/秘密鍵をそのまま使う場合の実装」と同じ)

 

#####################################################################
#  CSP キーコンテナに保存されている秘密鍵を使って文字列を復号化する
#####################################################################
function RSADecryptoCSP($ContainerName, $EncryptoString){
    # アセンブリロード
    Add-Type -AssemblyName System.Security

    # バイト配列にする
    $ByteData = [System.Convert]::FromBase64String($EncryptoString)

    # CspParameters オブジェクト作成
    $CSPParam = New-Object System.Security.Cryptography.CspParameters

    # マシンストアを使用する(デフォルトはユーザーストア。これを有効にするとマシンストアが使用される)
    # $CSPParam.Flags = [System.Security.Cryptography.CspProviderFlags]::UseMachineKeyStore

    # CSP キーコンテナ名
    $CSPParam.KeyContainerName = $ContainerName

    # RSACryptoServiceProviderオブジェクト作成し秘密鍵を取り出す
    $RSA = New-Object System.Security.Cryptography.RSACryptoServiceProvider($CSPParam)

    # 復号
    $DecryptedData = $RSA.Decrypt($ByteData, $False)

    # 文字列にする
    $PlainString = [System.Text.Encoding]::UTF8.GetString($DecryptedData)

    # オブジェクト削除
    $RSA.Dispose()

    return $PlainString
}

 

 

CSP キーコンテナの管理

CSP キーコンテナは独立して使用できる管理ツールがないので、管理も PowerShell で実装します。

##################################################
# CSP キーコンテナ削除
##################################################
function RSARemoveCSP($ContainerName){
    # アセンブリロード
    Add-Type -AssemblyName System.Security

    # CspParameters オブジェクト作成
    $CSPParam = New-Object System.Security.Cryptography.CspParameters

    # マシンストアを使用する(デフォルトはユーザーストア。これを有効にするとマシンストアが使用される)
    # $CSPParam.Flags = [System.Security.Cryptography.CspProviderFlags]::UseMachineKeyStore

    # CSP キーコンテナ名
    $CSPParam.KeyContainerName = $ContainerName

    # RSACryptoServiceProviderオブジェクト作成
    $RSA = New-Object System.Security.Cryptography.RSACryptoServiceProvider($CSPParam)

    # CSP キーコンテナ削除
    $RSA.PersistKeyInCsp = $False
    $RSA.Clear()

    # オブジェクト削除
    $RSA.Dispose()

    return
}

 

##################################################
# CSP キーコンテナのエクスポート
##################################################
function RSAExportCSP($ContainerName){
    # アセンブリロード
    Add-Type -AssemblyName System.Security

    # CspParameters オブジェクト作成
    $CSPParam = New-Object System.Security.Cryptography.CspParameters

    # マシンストアを使用する(デフォルトはユーザーストア。これを有効にするとマシンストアが使用される)
    # $CSPParam.Flags = [System.Security.Cryptography.CspProviderFlags]::UseMachineKeyStore

    # CSP キーコンテナ名
    $CSPParam.KeyContainerName = $ContainerName

    # RSACryptoServiceProviderオブジェクト作成
    $RSA = New-Object System.Security.Cryptography.RSACryptoServiceProvider($CSPParam)

    # エクスポート
    $ByteData = $RSA.ExportCspBlob($True)

    # 文字列にする
    $ExpoprtString = [System.Convert]::ToBase64String($ByteData)

    # オブジェクト削除
    $RSA.Dispose()

    return $ExpoprtString
}

 

##################################################
# CSP キーコンテナのインポート
##################################################
function RSAImportCSP($ContainerName, $ExpoprtString){
    # アセンブリロード
    Add-Type -AssemblyName System.Security

    # バイト配列にする
    $ByteData = [System.Convert]::FromBase64String($ExpoprtString)

    # CspParameters オブジェクト作成
    $CSPParam = New-Object System.Security.Cryptography.CspParameters

    # マシンストアを使用する(デフォルトはユーザーストア。これを有効にするとマシンストアが使用される)
    # $CSPParam.Flags = [System.Security.Cryptography.CspProviderFlags]::UseMachineKeyStore

    # CSP キーコンテナ名
    $CSPParam.KeyContainerName = $ContainerName

    # RSACryptoServiceProviderオブジェクト作成
    $RSA = New-Object System.Security.Cryptography.RSACryptoServiceProvider($CSPParam)

    # インポート
    $RSA.ImportCspBlob($ByteData)

    # オブジェクト削除
    $RSA.Dispose()

    return
}

 

こんな感じで使います。

# 平文
$PlanText = "ABCDEFghijk"

# CSP キーコンテナ名
$CSPName = "MuraTest"

# 鍵作成
$PublicKey = RSACreateKeyCSP $CSPName

# 暗号文
$EncryptoString = RSAEncrypto $PublicKey $PlanText

# 復号
$DecryptoString = RSADecryptoCSP $CSPName $EncryptoString

# CSP コンテナ Export
$ExportString = RSAExportCSP $CSPName

# CSP コンテナ 削除
RSARemoveCSP $CSPName

# CSP コンテナ Import
RSAImportCSP $CSPName $ExportString

 

CSP キーコンテナに秘密鍵を格納しても、秘密鍵の Export 禁止とか、Export したデーターのパスワード保護とかされないので、セキュア運用する場合は証明書ハンドリングの方が実用的かも?

スケジュールジョブ(PowerShell)でパスワードをセキュアに使う(証明書編)
http://www.vwnet.jp/Windows/WS12R2/Password/CertPassword.htm

 

 

関連情報

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

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

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

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

スケジュールジョブ(PowerShell)でパスワードをセキュアに使う(証明書編)
http://www.vwnet.jp/Windows/WS12R2/Password/CertPassword.htm

PowerShell で公開鍵方式暗号ファイルを交換をする
http://www.vwnet.jp/Windows/PowerShell/PublicKeyCrypto.htm

 

 

back.gif (1980 バイト)

home.gif (1907 バイト)

Copyright © MURA All rights reserved.