Я пытаюсь использовать BouncyCastle в Powershell для отправки пасты в PrivateBin API. Результат на данный момент:
- Работает локальное шифрование + дешифрование с помощью BouncyCastle.
- Работает отправка вставки в различные экземпляры PrivateBin
- Открыть вставку в браузере + Расшифровать Вставка, возвращаемая API, не работает
- Веб-сайт запрашивает пароль (но не определен)
Кто-нибудь знает, как использовать BouncyCastle с нужными параметрами для PrivateBin?
function SimpleEncrypt {
Param(
[string]$secretmessage,
[byte[]]$key,
[byte[]]$nonSecretPayload = $null
)
if ([string]::IsNullOrEmpty($secretmessage)) {
throw "Secret message Required!"
}
$nonSecretPayload = [byte[]]::new($null) #force set $null
$plainText = [system.Text.encoding]::UTF8.GetBytes($secretmessage)
$nonce = [byte[]]::new(16)
$crypto = [System.Security.Cryptography.RNGCryptoServiceProvider]::new()
$crypto.GetNonZeroBytes($nonce)
$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, $nonce, $nonSecretPayload) #payload als byte!!!
$cipher.Init($true, $parameters)
$cipherText = [byte[]]::new($cipher.GetOutputSize($plainText.Length))
$len = $cipher.ProcessBytes($plainText, 0, $plainText.Length, $cipherText, 0)
$null = $cipher.DoFinal($cipherText, $len)
$authtag = $cipher.GetMac() #auto appended using DoFinal()
$combinedStream = [System.IO.MemoryStream]::new()
$binaryWriter = [System.IO.BinaryWriter]::new($combinedStream)
#$binaryWriter.Write($nonSecretPayload)
$binaryWriter.Write($nonce)
$binaryWriter.Write($cipherText)
$cipherText = $combinedStream.ToArray()
return @{
cipherText = [convert]::ToBase64String($cipherText)
nonce = $nonce
mactag = $authtag
key = $kdfkey
}
}
function SimpleDecrypt {
Param(
[string]$encryptedMessage,
[byte[]]$key,
[int]$nonSecretPayloadLength = 0
)
if ([string]::IsNullOrEmpty($encryptedMessage)) {
throw "Secret message Required!"
}
$encbyteMessage = [byte[]][convert]::FromBase64String($encryptedMessage)
$cipherStream = [System.IO.MemoryStream]::new($encbyteMessage)
$cipherReader = [System.IO.BinaryReader]::new($cipherStream)
$nonSecretPayload = $cipherReader.ReadBytes($nonSecretPayloadLength)
$nonce = $cipherReader.ReadBytes(16)
$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), $MacBitSize, $nonce, $nonSecretPayload) #payload als byte!!!
$cipher.Init($false, $parameters)
$cipherText = $cipherReader.ReadBytes($encbyteMessage.Length - $nonSecretPayloadLength - $nonce.Length)
$plainText = [byte[]]::new($cipher.GetOutputSize($cipherText.Length))
$len = $cipher.ProcessBytes($cipherText, 0, $cipherText.Length, $plainText, 0)
$null = $cipher.DoFinal($plainText, $len)
return [system.Text.encoding]::UTF8.GetString($plainText)
}
function PBKDF2_SHA256_GetHash {
Param([string]$password, [byte[]]$salt, [int]$iterations, [int]$hashByteSize)
$pdb = [Org.BouncyCastle.Crypto.Generators.Pkcs5S2ParametersGenerator]::new([Org.BouncyCastle.Crypto.Digests.Sha256Digest]::new())
$pdb.init([Org.BouncyCastle.Crypto.PbeParametersGenerator]::Pkcs5PasswordToBytes($password.ToCharArray()), $salt, $iterations)
$key = $pdb.GenerateDerivedMacParameters($hashByteSize * 8)
return [byte[]]$key.GetKey()
}
#example
[byte[]]$salt = [byte[]]::new(8)
$crypto = [System.Security.Cryptography.RNGCryptoServiceProvider]::new()
$crypto.GetNonZeroBytes($salt)
$kdfsaltb64encoded = [convert]::ToBase64String($salt)
$kdfkeygen = [Org.BouncyCastle.Crypto.Generators.Pkcs5S2ParametersGenerator]::new([Org.BouncyCastle.Crypto.Digests.Sha256Digest]::new())
$kdfkeygen.Init("", $salt, 100000)
$kdfkeygenderivedparams = ($kdfkeygen.GenerateDerivedParameters(128))
[byte[]]$kdfkey = $kdfkeygenderivedparams.getKey()
$kdfkeyb64encoded = [convert]::ToBase64String($kdfkey)
$enc = SimpleEncrypt -secretmessage "hallo welt" -key $kdfkey
$iv = $enc.nonce
$ivb64encoded = [convert]::ToBase64String($iv)
$dec = SimpleDecrypt -key $kdfkey -encryptedMessage $enc.cipherText
$ciphertext = $enc.cipherText
$postbody = @{
v= "2"
adata = @(@("$ivb64encoded","$kdfsaltb64encoded",100000,256,128,"aes","gcm","none"),"plaintext",0,0)
ct = "$($ciphertext)"
meta = @{
expire = "1day"
}
}
$body = $postbody | convertto-json | out-string
$uri = "https://cpaste.org"
$header = @{"X-Requested-With" = "JSONHttpRequest"}
$response = Invoke-RestMethod -Method POST -Uri "$($uri)" -Headers $header -Body $body
$response
Моя попытка расшифровки с URL:
$header = @{"X-Requested-With" = "JSONHttpRequest"}
$decrypturl = "https://cpaste.org/?29cce083dbb9b6d8#FU4BjDSip6yv4HEmAJYzEJgwaMNxyCLih17vE4auf6vJ"
$decdata = Invoke-RestMethod -Headers $header -Uri $decrypturl -method get
$iv = [convert]::FromBase64String($decdata.adata[0][0])
$salt = [convert]::FromBase64String($decdata.adata[0][1])
$key = PBKDF2_SHA256_GetHash -salt $salt -iterations 100000 -hashByteSize 16
SimpleDecrypt -key $key -encryptedMessage $decdata.ct
$ciphertexttag = [convert]::FromBase64String($decdata.ct)
и соответствующее сообщение об ошибке:
..."DoFinal" mit 2 Argument(en): "mac check in GCM failed"