Слишком короткий выходной буфер Сообщение при использовании BouncyCastle Crypto в Powershell / C# - PullRequest
0 голосов
/ 04 марта 2020

Когда я пытаюсь зашифровать строку с помощью Bouncycastle V1.8.5 (aes256, gcm, nopadding), я получаю сообщение об ошибке

Исключение, вызывающее "DoFinal" с аргументом "2" : "Выходной буфер слишком короткий"

Мой код:

Add-Type -Path "C:\Program Files\PackageManagement\NuGet\Packages\BouncyCastle.1.8.5\lib\BouncyCastle.Crypto.dll"
$secretmessage = "Totalgeheim!"
$secretmessageBytes = [System.Text.Encoding]::UTF8.GetBytes($secretmessage)
$bytes = [system.byte[]]::CreateInstance([System.Byte],16)
[System.Security.Cryptography.RNGCryptoServiceProvider]::new().GetNonZeroBytes($bytes)
$key = $bytes
$bytes = [system.byte[]]::CreateInstance([System.Byte],8)
([System.Security.Cryptography.RNGCryptoServiceProvider]::new()).GetNonZeroBytes($bytes)
$salt = $bytes
[byte]$nonSecretPayload = $null
$cipher = [Org.BouncyCastle.Crypto.Modes.GcmBlockCipher]::new([Org.BouncyCastle.Crypto.Engines.AesEngine]::new())
$parameters = [Org.BouncyCastle.Crypto.Parameters.AeadParameters]::new([Org.BouncyCastle.Crypto.Parameters.KeyParameter]::new($key), 128, $salt, $nonSecretPayload) #payload als byte!!!
$cipher.Init($true, $parameters)
$ciphertext = [System.Text.Encoding]::UTF8.GetBytes($cipher.GetOutputSize($secretmessageBytes.Length))
$len = $cipher.ProcessBytes($secretmessageBytes, 0, $secretmessageBytes.Length, $ciphertext, 0)
$cipher.DoFinal($ciphertext, $len)

У кого-нибудь есть идеи, почему это не работает, как ожидалось?

1 Ответ

0 голосов
/ 04 марта 2020

$cipher.GetOutputSize() будет выводить длину байта как целое число - передача его в UTF8Encoding.GetBytes(), неявное преобразование его в строку, приведет к массиву всего в несколько байтов.

Замените эту строку :

$ciphertext = [System.Text.Encoding]::UTF8.GetBytes($cipher.GetOutputSize($secretmessageBytes.Length))

... с:

$ciphertext = [byte[]]::new($cipher.GetOutputSize($secretmessageBytes.Length))

Если ваш сценарий должен работать на версиях, более старых, чем PowerShell 5.0, используйте New-Object или Array.CreateInstance() вместо:

$cipherText = [array]::CreateInstance([byte], $cipher.GetOutputSize($secretmessageBytes.Length))
# or 
$cipherText = New-Object 'byte[]' -ArgumentList $cipher.GetOutputSize($secretmessageBytes.Length)
...