3

AWS KMS を使用してテキストを暗号化し、powershell スクリプトを作成しようとしています。そのため、出力で返される KMS マスター キーをNew-KMSDataKey暗号化していました。plaintextDataKeyciphertextblob

現在plaintextDataKey、平文を暗号化するために使用してInvoke-KMSEncryptいますが、以下に示すように無効な操作エラーが発生します。

ここに画像の説明を入力

以下は私のスクリプトです:

param([string]$zonesecret, [string]$KMSKey, [string]$Keyspec, [string]$region= 'us-east-1', [string]$AccessKey, [string]$SecretKey)

# splat
$splat = @{KeyId=$KMSKey; KeySpec=$Keyspec; Region=$region}
# generate a data key 
$datakey = New-KMSDataKey @splat

$plaintextDataKey = [Convert]::ToBase64String($datakey.Plaintext.ToArray())
$encryptedDataKey = [Convert]::ToBase64String($datakey.CiphertextBlob.ToArray())
Write-Host $plaintextDataKey
Write-Host $encryptedDataKey

#encrypt using aes-256; pass zonesecret and plaintextDataKey
# memory stream
[byte[]]$byteArray = [System.Text.Encoding]::UTF8.GetBytes($zonesecret)
$memoryStream = New-Object System.IO.MemoryStream($byteArray,0,$byteArray.Length)

$splat = @{Plaintext=$memoryStream; KeyId=$plaintextDataKey; Region=$region;}
if(![string]::IsNullOrEmpty($AccessKey)){$splat += @{AccessKey=$AccessKey;}}
if(![string]::IsNullOrEmpty($SecretKey)){$splat += @{SecretKey=$SecretKey;}}

# encrypt
**$encryptedMemoryStream = Invoke-KMSEncrypt @splat** # ERROR: 
Write-Host $encryptedMemoryStream

$base64encrypted = [System.Convert]::ToBase64String($encryptedMemoryStream.CiphertextBlob.ToArray())
Write-Host $base64encrypted

正しくするにはどうすればよいですか?私はここで何か悪いことをしていますか? データを暗号化するためのコマンドレットは他にありません: http://docs.aws.amazon.com/powershell/latest/reference/Index.html

誰でもここで助けてもらえますか?上記のプレーンテキスト データ キーを使用してコンテンツを暗号化するにはどうすればよいですか?

4

1 に答える 1

3

提示されたコードには、この動物の一部として適切なボーンが多数含まれていますが、KMS を支える概念の一部が欠落しているなど、動作を妨げるいくつかの問題があります。データ キーの使用は KMS を操作する優れた方法ですが、その場合は、提供されたキーを使用してデータを暗号化および復号化するホスト システムの機能に依存する必要があることを理解する必要があります。

KMS データ キーは、エンベロープ暗号化のサポートを提供します。KMS が提供する暗号化と復号化は、データではなくキー自体に対して行われます。データ キーを使用する場合は、KMS が提供するプレーンテキスト キーを使用してデータを暗号化し、提供されたキーの暗号化バージョンをデータと共に保存する必要があります。暗号文を復号化するときは、KMS を使用してデータ キーを復号化し、データ キー暗号文キーから派生した平文を AES 復号化のキーとして使用します。

KMSキーIDをスクラブして、提供されたコードから派生した作業用スクリプトのペアからのテスト実行の例を次に示します。

PS C:\Users\Administrator> $kmskey =  'abcdef01-2345-6789-0123-0123456789ab'
PS C:\Users\Administrator> ./encrypt.ps1 "This is a test" -KMSKey $kmskey | ConvertTo-Json > message.json
PS C:\Users\Administrator> type message.json
{
    "encryptedDataKey":      "AQEDAHix3RkObJxNv8rJGn2Oyy0bRR9GOvSOFTHR2OQ6SBt76wAAAH4wfAYJKoZIhvcNAQcGoG8wbQIBADBoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDGui8Ycxf+XoJkAkuQIBEIA7R6eiM6PREoJdnaNA5gaeZfcSA3fC3UlRYGE6Epo96U+SqYPYzyXKOEyqB+1+3pCHz2zgZZlbcgzThrs=",
    "ciphertext":  "76492d1116743f0423413b16050a5345MgB8AGwANgBEAEwAaQB5AFQAOQByAGgAYgBPAGcAagBKAGIAQQBBAEwAQgBkAEEAPQA9AHwAMgAzADIAYgA0AGEAYgBlADgAMAA5AGQAZABkADEAOQBlADkAYgBjADgAZgA2ADgAMAA0ADgAZABhADQANQA5ADYAMABiAGIAYQAxADQANABiADAAOAA2ADYANgBlAGYANwAxADkANQA2ADEAMgBjAGEANQBjADAAYgBjAGMANAA=\r\n"
}
PS C:\Users\Administrator> ConvertFrom-JSON $(Get-Content .\message.json | Out-String) | .\decrypt.ps1 -KMSKey $kmskey

plaintext
---------
This is a test

PS C:\Users\Administrator> ./encrypt.ps1 "Super Secret Stuff" -KMSKey $kmskey | .\decrypt.ps1 -KMSKey $kmskey

plaintext
---------
Super Secret Stuff

暗号化スクリプトと復号化スクリプトは次のとおりです。

暗号化.ps1

param(
    [Parameter(Mandatory=$True)]
    [string]$secret,

    [Parameter(Mandatory=$True)]
    [string]$KMSKey,

    [string]$Keyspec = 'AES_256',

    [string]$region = 'us-east-1'
)

# generate a data key
$datakey = New-KMSDataKey -KeyId $KMSKey -KeySpec $Keyspec -Region $region

[byte[]]$plaintextDataKey = $datakey.Plaintext.ToArray()
[byte[]]$encryptedDataKey = $datakey.CiphertextBlob.ToArray()

# Encrypt using AES using Powershell's SecureString facilities
# Any AES encryption method would do, this is just the most convenient
# way to do this from Powershell.
#
# Note that trying to use the Invoke-KMSEncrypt method is not what you want
# to do when using Data Keys and envelope encryption.
$encrypted = ConvertTo-SecureString $secret -AsPlainText -Force `
    | ConvertFrom-SecureString -key $plaintextDataKey `
    | Out-String

# Thanks to http://stackoverflow.com/a/24778625/424301 
# for the tip on using psobject return values and
# ValueFromPipelineByPropertyName parameters (see decrypt.ps1)
return New-Object psobject -property @{ 
    "ciphertext" = $encrypted;
    "encryptedDataKey" = $([Convert]::ToBase64String($encryptedDataKey))
}

復号化.ps1

[CmdletBinding()]
param(
    [Parameter(Mandatory=$true,
        Position=0,
        ValueFromPipelineByPropertyName=$true)]
    [string]$ciphertext,

    [Parameter(Mandatory=$true,
        Position=1,
        ValueFromPipelineByPropertyName=$true)]
    [string]$encryptedDataKey,

    [Parameter(Mandatory=$true,
        Position=2,
        ValueFromPipelineByPropertyName=$true)]
    [string]$KMSKey
)

[byte[]]$bytes = $([Convert]::FromBase64String($encryptedDataKey))
$stream = new-object System.IO.MemoryStream (,$bytes)

# decrypt the data key 
$response = Invoke-KMSDecrypt -CiphertextBlob $stream
if ($response.HttpStatusCode -eq 200) {
    $dataKey = $response.Plaintext.ToArray()
} else {
    throw "KMS data key decrypt failed: $(ConvertTo-Json $response)"
}
# Now AES decrypt the ciphertext and emit the plaintext
$secureString = ConvertTo-SecureString $ciphertext -key $dataKey
$plaintext =  [Runtime.InteropServices.Marshal]::PtrToStringAuto( `
    [Runtime.InteropServices.Marshal]::SecureStringToBSTR($secureString))
return  New-Object psobject -property @{
    "plaintext" = $plaintext
}
于 2016-12-15T05:33:31.987 に答える