В представленном коде есть много правильных костей, чтобы быть частью этого животного, но есть несколько проблем, которые мешают ему работать, в том числе отсутствие некоторых концепций, лежащих в основе KMS. Использование ключей данных - отличный способ работы с KMS, но когда вы это делаете, вы должны понимать, что вам нужно полагаться на способность вашей хост-системы шифровать и дешифровать данные с помощью предоставленных ключей.
Ключи данных KMS обеспечивают шифрование конверта, а также шифрование и дешифрование. KMS предоставляет сам ключ, а не ваши данные. При использовании ключей данных вы должны использовать открытый текстовый ключ, который KMS предоставляет для шифрования ваших данных, а затем сохранить зашифрованную версию ключа, который вам был предоставлен вместе с данными. Когда пришло время расшифровать ваш зашифрованный текст, вы используете KMS для расшифровки ключа данных, а затем используете открытый текст, полученный из ключа зашифрованного текста ключа данных, в качестве ключа в расшифровке AES.
Вот пример тестового запуска из рабочей пары скриптов, которые я извлек из предоставленного вами кода, с очищенным идентификатором ключа KMS:
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
А вот скрипты шифрования и дешифрования:
encrypt.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))
}
decrypt.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
}
person
obscurerichard
schedule
15.12.2016