Le code présenté contient plusieurs des bons os pour faire partie de cet animal, mais il a plusieurs problèmes qui l'empêchent de fonctionner, y compris l'absence de certains concepts sous-jacents à KMS. L'utilisation de clés de données est une excellente façon de travailler avec KMS, mais lorsque vous faites cela, vous devez comprendre que vous devez compter sur la capacité de votre système hôte à crypter et déchiffrer les données avec les clés fournies.
Les clés de données KMS fournissent envelope encryption et le décryptage et le décryptage fournis par KMS concernent la clé elle-même et non vos données. Lorsque vous utilisez des clés de données, vous devez utiliser la clé en clair que le KMS fournit pour chiffrer vos données, puis stocker la version chiffrée de la clé fournie avec les données. Lorsqu'il est temps de décrypter votre texte chiffré, vous utilisez KMS pour déchiffrer la clé de données, puis utilisez le texte en clair dérivé de la clé de chiffrement de clé de données comme clé dans votre déchiffrement AES.
Voici un exemple d'un essai de paire travail de scripts que je Dérivée à partir du code que vous avez fourni, avec l'ID de clé KMS frotté:
PS C:\Users\Administrator> $kmskey = 'abcdef01-2345-6789-0123-ab'
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
Et voici le chiffrement et le déchiffrement des scripts:
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
}