Introdução


Em algum momento durante nossa vida de scripting guy, vamos precisar criptografar um texto no powershell, 
seja por questões de segurança, por exemplo um script que vá salvar alguma senha em um banco de dados, ou enviar algum dado por email 
que não posa ser lido por qualquer um.

Nesse artigo veremos o passo a passo de como trabalhar com criptografia de textos utilizando uma chave no Powershell.

Criptografando


Bem o primeiro passo é criptografar um texto, para isso utilizamos o bloco de scripts a baixo (Explicações depois):

$IV = (0x50,0x08,0xF1,0xDD,0xDE,0x3C,0xF2,0x18,0x44, 0x74, 0x19, 0x2C, 0x53, 0x49, 0xAB, 0xBC)
$Chave = [Text.Encoding]::ASCII.GetBytes("ChaveDeCriptografiaCom32Letras..")
$BytesTexto = [Text.Encoding]::UTF8.GetBytes("esse texto vai ser criptografado e é uma mensagem secreta para a technet wiki!")
$Rijndael = new-Object System.Security.Cryptography.RijndaelManaged
$Rijndael.KeySize = 256
$ms = new-Object IO.MemoryStream
$c = new-Object Security.Cryptography.CryptoStream $ms,$Rijndael.CreateEncryptor($Chave,$IV),"Write"
$sw = new-Object IO.StreamWriter $c
$sw.write($BytesTexto,0,$BytesTexto.Length)    
$sw.Close()
$c.Close()
$ms.Close()
$Rijndael.Clear()
[byte[]]$result = $ms.ToArray()  
$encstring = [Convert]::ToBase64String($result)
Write-Host "Texto criptografado: "$encstring 


As explicações por linha são:
  1. determina o vetor de inicialização para o algorítimo de criptografia na variável $IV.
  2. Pega os bytes da chave de criptografia .
  3. Pega os bytes do texto a ser criptografado.
  4. Cria um novo objeto do tipo RijndaelManaged, que vai ser utilizado para criptografar o texto.
  5. Determina o tamanho da chave de criptografia.
  6. Cria um novo objeto MemoryStream.
  7. Cria o objeto CryptoStream passando como parâmetro o encriptador e a chave de criptografia.
  8. Cria um objeto de Stream Writer passando o criptostream.
  9. Escreve a os bytes do texto e a sua lagura no stream do criptografador.
  10. Fecha o objetos criado anteriormente.
  11. Fecha o objetos criado anteriormente.
  12. Fecha o objetos criado anteriormente.
  13. Fecha o objetos criado anteriormente.
  14. Salva no Result a Array presente na MemoryStream.
  15. Converte o resultado final de bytes para uma string com base 64.
  16. Exibe o texto criptografado na tela.

Um pouco complicado? sim também acho sugiro algumas leituras complementares para entender melhor o funcionamento desse processo
http://msdn.microsoft.com/en-us/library/system.security.cryptography.rijndael.aspx

Descriptografando


Tão importante quanto criptografar é saber como descriptografar, a baixo segue o código para descriptografar e em seguida as explicações:

$IV = (0x50,0x08,0xF1,0xDD,0xDE,0x3C,0xF2,0x18,0x44, 0x74, 0x19, 0x2C, 0x53, 0x49, 0xAB, 0xBC)
$Chave = [Text.Encoding]::ASCII.GetBytes("ChaveDeCriptografiaCom32Letras..")
$BytesTextoCriptografado = [Convert]::FromBase64String("mFoSdEP4Ua5ZXYAUs19BpbNYy44PG7h/2YGJe9xl4qjPPE2gggeQq9In5NqOEi89yaNNSj1ZBkc6opom+7MTtUEL7z8RAolIfLIK109G1V4=")
$Rijndael = new-Object System.Security.Cryptography.RijndaelManaged
$Rijndael.KeySize = 256;
$ms = new-Object IO.MemoryStream
$c = new-Object Security.Cryptography.CryptoStream $ms,$Rijndael.CreateDecryptor($Chave,$IV),"Write"
$c.write($BytesTextoCriptografado, 0,$BytesTextoCriptografado.Length)
$c.FlushFinalBlock();
$TextoLimpo = [Text.Encoding]::UTF8.GetString($ms.ToArray())
$c.Close()
$ms.Close()
Write-Host $TextoLimpo


Vamos então as explicações, 

  1. Determina o vetor de inicialização para o algorítimo de descriptografia na variável $IV.
  2. Determina chave de descriptografia.
  3. Recebe o texto cifrado e pega os bytes do mesmo.
  4. Cria objeto RijndaelManaged.
  5. Determina tamanho da chave.
  6. Cria um novo objeto MemoryStream.
  7. Cria o objeto CryptoStream passando como parâmetro o decryptor e a chave de descriptografia.
  8. Aqui é onde a magica rola, utiliza o CryptoStream para descriptografar os bytes do texto cifrado.
  9. Limpa o crypto.
  10. Converte os bytes descriptografados para string.
  11. Fecha objetos abertos.
  12. Fecha objetos abertos.
  13. Retorna o texto decifrado!

Função Pronta


Então já sabemos como cifrar e decifrar que tal montarmos uma função para facilitar o processo?

Function Get-Crypto($Texto,$Senha,$Acao){
switch ($Acao){
"Decrypt" {
                write-host "Decifrando $texto com a senha: $senha"
                $IV = (0x50,0x08,0xF1,0xDD,0xDE,0x3C,0xF2,0x18,0x44, 0x74, 0x19, 0x2C, 0x53, 0x49, 0xAB, 0xBC)
                $Chave = [Text.Encoding]::ASCII.GetBytes($Senha)
                $BytesTextoCriptografado = [Convert]::FromBase64String($Texto)
                $Rijndael = new-Object System.Security.Cryptography.RijndaelManaged
                $Rijndael.KeySize = 256;
                $ms = new-Object IO.MemoryStream
                $c = new-Object Security.Cryptography.CryptoStream $ms,$Rijndael.CreateDecryptor($Chave,$IV),"Write"
                $c.write($BytesTextoCriptografado, 0,$BytesTextoCriptografado.Length)
                $c.FlushFinalBlock();
                $TextoLimpo = [Text.Encoding]::UTF8.GetString($ms.ToArray())
                $c.Close()
                $ms.Close()
                $TextoLimpo

        }
"Encrypt" {
            write-host "Cifrando $Texto com a senha: $Senha"
            $IV = (0x50,0x08,0xF1,0xDD,0xDE,0x3C,0xF2,0x18,0x44, 0x74, 0x19, 0x2C, 0x53, 0x49, 0xAB, 0xBC)
            $Chave = [Text.Encoding]::ASCII.GetBytes($Senha)
            $BytesTexto = [Text.Encoding]::UTF8.GetBytes($Texto)
            $Rijndael = new-Object System.Security.Cryptography.RijndaelManaged
            $Rijndael.KeySize = 256
            $ms = new-Object IO.MemoryStream
            $c = new-Object Security.Cryptography.CryptoStream $ms,$Rijndael.CreateEncryptor($Chave,$IV),"Write"
            $sw = new-Object IO.StreamWriter $c
            $sw.write($BytesTexto,0,$BytesTexto.Length)    
            $sw.Close()
            $c.Close()
            $ms.Close()
            $Rijndael.Clear()
            [byte[]]$result = $ms.ToArray()  
            $encstring = [Convert]::ToBase64String($result)
            $encstring
        }
}
}


um exemplo de utilização dessa função:

Get-Crypto -Texto "Mensagem secreta!!!!" -Senha "ChaveDeCriptografiaCom32Letras.." -Acao "Encrypt"
Get-Crypto -Texto "1yxT0dGwtzFUbJy8veh/NsriGJMg0rAHQnTSFHfoHrI=" -Senha "ChaveDeCriptografiaCom32Letras.." -Acao "Decrypt"





Referencias

Esse artigo foi feito com conhecimento adquiro da necessidade de efetuar a criptografia de dados via script, originalmente esse codigo foi feito em C# pelo meu amigo Lucas Pfeiffer do blog http://muitomaisque.net/ e eu fiz a conversão para Powershell.

Você pode ler mais sobre Rijndael no link na msdns
http://technet.microsoft.com/pt-br/library/dd347656.aspx

Artigo originalmente publicado por:
Matheus Kamphorst | Blog: http://howtoserver.com