rtumaykin / ssis-build

A set of utilities that allow to autonomously build a Visual Studio SSIS project (dtproj) into a deployment package (ispac), and deploy the package to an SSIS catalog
Apache License 2.0
52 stars 39 forks source link

`DecryptElement` - Garbage Data And Invalid Padding #48

Open mattcargile opened 2 years ago

mattcargile commented 2 years ago

I'm exploring decrypting dtsx files using the same logic in the aforementioned method found below. I'm using pwsh.exe and I can only decrypt mostly successfully if I use [System.Security.Cryptography.PaddingMode]::ISO10126 otherwise I get StreamReader errors about padding ( e.g. Write-Error: Exception calling "ReadToEnd" with "0" argument(s): "Padding is invalid and cannot be removed." ). https://github.com/rtumaykin/ssis-build/blob/5a0187b788934ed919daa7ed929605582dcca29e/src/SsisBuild.Core/ProjectManagement/ProjectFile.cs#L246 Additionally, I receive weird characters at beginning like the below. image

Below is the script function I built that mostly mirrors the aforementioned method. I can only figure at this point either I have some weird old 2008/2012 dtsx file or I've got some incompatibility with .NET.

 [CmdletBinding()]
 param (
     [Parameter()]
     [string]
     $Path = '.\tripledes-cbc.dtsx',
     # Password
     [Parameter()]
     [securestring]
     $Password = (Read-Host -AsSecureString -Prompt 'Enter Password to Decrypt the dtsx file')
 )

$xml = [xml](Get-Content $Path -Raw)
$encDt = $xml.EncryptedData
$p = [pscredential]::new( 'Dummy' , $Password).GetNetworkCredential().Password
$salt = [System.Convert]::FromBase64String( $encDt.Salt )
$iv = [System.Convert]::FromBase64String( $encDt.IV )
$cipDt = [System.Convert]::FromBase64String( $encDt.CipherData.CipherValue )

try {
    $tdes = [System.Security.Cryptography.TripleDES]::Create()
    $tdes.IV = $iv
    $tdes.Padding = [System.Security.Cryptography.PaddingMode]::ISO10126
    $tdes.Mode = [System.Security.Cryptography.CipherMode]::CBC
    $pdb = [System.Security.Cryptography.PasswordDeriveBytes]::new( $p , $salt)
    $tdes.Key = $pdb.CryptDeriveKey('TripleDES' , 'SHA1', 192 , $tdes.IV )
    $memStrm = New-Object System.IO.MemoryStream -ArgumentList (,$cipDt)
    $cryStrm = New-Object System.Security.Cryptography.CryptoStream -ArgumentList @( 
        $memStrm
        $tdes.CreateDecryptor()
        [System.Security.Cryptography.CryptoStreamMode]::Read 
    )
    $strmRdr = New-Object System.IO.StreamReader -ArgumentList @( $cryStrm, [System.Text.Encoding]::UTF8 )
    $strmRdr.ReadToEnd()
}
catch {
    Write-Error $_
}
finally {
    if($aes){$aes.Dispose()}
    if($memStrm){$memStrm.Dispose()}
    if($cryStrm){$cryStrm.Dispose()}
    if($strmRdr){$strmRdr.Dispose()}
}