powershellencryptionsecurestring

Encrypted the $PROFILE file successfully, but getting back the exact decrypted $PROFILE file not working


I have Powershell 5.x installed in my Windows 11 system. I have some secured keys stored in my Powershell $PROFILE global script for easy command-running for GitHub and stuff.

Now I have successfully encrypted (and secured) the $PROFILE file and stored it at $PROFILE.cryptd path through this function:


function Encrypt-Profile {
  # Paths for the profile file and the encrypted profile
  $ProfilePath = $PROFILE
  $CryptdProfilePath = "$PROFILE.cryptd"

  # Read the plaintext profile file
  $plainText = Get-Content -Path $ProfilePath -Raw

  # Convert the text into a secure string
  $secureString = ConvertTo-SecureString -String $plainText -AsPlainText -Force

  # Encrypt the secure string and convert it to a string representation
  $encryptedText = $secureString | ConvertFrom-SecureString

  # Save the encrypted text to a file
  Set-Content -Path $CryptdProfilePath -Value $encryptedText
  Write-Host "Profile encrypted and saved to $CryptdProfilePath"
}

But when I try to reverse steps in the Decrypt-Profile function, which is suppose to exactly reverse the above function and give back the plaintext decrypted $PROFILE at path $PROFILE.plaintxt, it instead throws error on the second line itself:

ConvertTo-SecureString : Input string was not in a correct format.

The Decrypt-Profile function that I am using is:

function Decrypt-Profile {
  # Paths for the profile file and the encrypted profile
  $ProfilePath = "$PROFILE.cryptd"
  $PlainTxtProfilePath = "$PROFILE.plaintxt"

  # Read the encrypted text from the file
  Echo "$PROFILE.cryptd"
  $encryptedText = Get-Content -Path $ProfilePath -Raw

  # Convert the encrypted text back into a secure string
  $secureString = $encryptedText | ConvertTo-SecureString

  # Convert the secure string back into plain text
  $decryptedText = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto(
    [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($secureString)
  )

  # Display the decrypted profile content
  # Write-Host "Decrypted Profile Content:"
  # Write-Host $decryptedText

  Set-Content -Path $PlainTxtProfilePath -Value $decryptedText
  Write-Host "Profile decrypted and saved to $PlainTxtProfilePath"
}

If I do ConvertFrom-SecureString during reading content of encrypted file like $encryptedText = Get-Content -Path $ProfilePath -Raw | ConvertFrom-SecureString in the decrypt function above I am getting error:

ConvertFrom-SecureString : The input object cannot be bound to any parameters for the command either because the command does not
take pipeline input or the input and its properties do not match any of the parameters that take pipeline input.

What am I doing wrong in Decrypt-Profile? I thought this would be in and out, if I reverse steps exactly.


Solution

  • Set-Content adds a trailing newline when you first write the encrypted string to disk - use String.Trim() to get rid of it when reading the contents back into memory:

      $encryptedText = Get-Content -Path $ProfilePath -Raw |ForEach-Object Trim
    

    ... or omit -Raw and read just the first line of the file instead:

      $encryptedText = Get-Content -Path $ProfilePath -TotalCount 1