Publicado en

Encriptar contraseñas con un certificado

En un post anterior vimos como crear contraseñas de manera automática con powershell y así tener más posibilidades de impresionar a nuestra chica. También igual nos era útil para otras cosas de sistemas, pero mola impresionar a una chica con comandos, que coño.

A veces, gestionar esas contraseñas en un script o en ficheros de configuración es complicado o sensible. Seguramente tu amigo de seguridad te de un par de ostias si encuentra las contraseñas escritas en claro o algún amigo chino o ruso te lo agradezca con un email y una fortuna enorme del rey de Wakanda

Encriptar de manera segura las contraseñas ya no será tu mayor problema. Vamos a crear un certificado

$cert = New-SelfSignedCertificate -Type DocumentEncryptionCertLegacyCsp -DnsName 'EncryptionCert' -HashAlgorithm SHA256

Con este certificado, que tiene una parte privada y otra publica vamos a jugar. Con la parte privada desencriptaremos contraseñas y con la parte publica las encriptaremos.

# Obtenemos el certificado del almacen mediante el nombre o cualquiera otra propiedad
$Cert = Get-ChildItem Cert:\LocalMachine\My | Where-Object {$_.Subject -like "*CN=EncryptionCert*"}

# Creamos el objeto de credenciales que queremos encriptar para no almacenarla en txt 
$cred=Get-Credential -Message "Rellena tus datos:" -UserName "Mi Usuario"
$Password=$cred.GetNetworkCredential().password

# Encriptamos la contraseña
$EncodedPwd = [system.text.encoding]::UTF8.GetBytes($Password)
$EncryptedBytes = $Cert.PublicKey.Key.Encrypt($EncodedPwd, $true)
$EncryptedPwd = [System.Convert]::ToBase64String($EncryptedBytes)

Así queda la encriptación

Ahora mismo ver la contraseña es como ver las pelis esas antiguas de canal + sin decodificador (si no entiendes esto eres demasiado joven)

Podemos utilizar este trozo de código completo para generar la contraseña cifrada y que nos devuelva el código que tenemos que colocar en nuestro script para poder desencriptarlo.

# Obtenemos el certificado del almacen mediante el nombre o cualquiera otra propiedad
$Cert = Get-ChildItem Cert:\LocalMachine\My | Where-Object {$_.Subject -like "*CN=EncryptionCert*"}

# Creamos el objeto de credenciales que queremos encriptar para no almacenarla en txt 
$cred=Get-Credential -Message "Rellena tus datos:" -UserName "Mi Usuario"
$Password=$cred.GetNetworkCredential().password

# Encriptamos la contraseña
$EncodedPwd = [system.text.encoding]::UTF8.GetBytes($Password)
$EncryptedBytes = $Cert.PublicKey.Key.Encrypt($EncodedPwd, $true)
$EncryptedPwd = [System.Convert]::ToBase64String($EncryptedBytes)
 
 
cls
 "Tu contraseña para $($cred.username): `n$EncryptedPwd"
    "`n"
    " Usa esto para tu script:"
    ' '
 
    "##################################### CREDENTIAL ############################################################"
    '$Cert = Get-ChildItem Cert:\LocalMachine\My | Where-Object {$_.Subject -like "*CN=MYEncryptionCert*"}'
    '$User=' + '"' + $($cred.UserName) + '"'
    '$EncryptedPwd =' + '"' + $EncryptedPwd + '"'
    '$EncryptedBytes = [System.Convert]::FromBase64String($EncryptedPwd)'
    '$DecryptedBytes = $Cert.PrivateKey.Decrypt($EncryptedBytes, $true)'
    '$DecryptedPwd = [system.text.encoding]::UTF8.GetString($DecryptedBytes)'
    '$SecurePassword  = convertto-securestring $DecryptedPwd -asplaintext -force'
    '$Cred = new-object -typename System.Management.Automation.PSCredential -ArgumentList $User,$SecurePassword'
    '##################################### CREDENTIAL ############################################################'
 
    ' '

Te genera algo así:

##################################### CREDENTIAL ############################################################
$Cert = Get-ChildItem Cert:\LocalMachine\My | Where-Object {$_.Subject -like "*CN=EncryptionCert*"}
$User="Usuario"
$EncryptedPwd ="KSMh+v9iAxuSu+SPya9dM34upJ6+JCTky0oA39uJQKGpSiBax/ZXLph7i0QjxOJPhQk+MnzZy2P9jRnaLAcbBOwxCcTf93CodkXb8ePBwnljtLe7XXjGiKE+nLDmP/cr5ltHYGzkERuczh6D+Oxtlhf0kDc2N7Gtzk9vd9nKxwu/Eo0RPbXYU89//EoZMOjNgntDYBA8z//yZl4UsrK/GUIUQA26plgUA0larc8kU0+ZfvuSiRyxP07mOwQveCTCtLpahFnLEn1tsEVkh4CzW4hRszegBop6QLykGX/Ne5VwAnCTvJ3KAov0hE4VLWCDqMVKtFJkirsrc2Lv1xBF67h4a9tL/gjlLPvqJSGhJc5Bh7tqw1MW1pOC1zBpc6hGoNKc0gQb1hBTYJ63V2dLgWx2l9dguspgBP6ki0yw/HfcRt2EHEW38NO67FvxWJrWk02ApE9+jNOYsKB/d5Dydr8gsjeAelyjqJGiKkb2xB2OP3B8sD4Xmc1w3wF2uC79JpLn5X9Zx+5cD9lOAa0kWr2eaxmdGoVnCo0e/m4zJHPH4TLBOLNqVVyfkWCXHO6wcFR6MW57JgHpjQxQeN5zM+imYUtHKSfPxWXz1tLYj/+RCct+k2poHwFiWW0D7u1hPNkWHzo3e4NLUkaENjl17wRuFLYJTdhqQpsEAIftD30vUOOoQ1s6drLPZ7ImAFgGUEo5ACK/ONyfj+UFAOVUH8+/swmNaHO87JnOkfCsfYFZWSxUIoVhC7mYmjOJJMfYwJsaFpfkbfd4YjsRl9bR1NRBjET2NUC1Nu4NehFLG25owR7xD7HV68PBy5Dgar2Hf5BsgtWwD+y1HIbV/4zFuYaORuvMiQEHpKU3N444iYB3qOHiA0844+XRiw5NWjOTV4AU9GO1IgGtBl94Dz8yDcOWg3JF0BuJOX4c4Rm13wD1N/z+Q9V+yn/baTOmkAkSVnsc5joiSan76/BBTo6Ewi12jhuhrrD98kItDPp9qpydmBWNst1MrRUgPOjwXnru"
$EncryptedBytes = [System.Convert]::FromBase64String($EncryptedPwd)
$DecryptedBytes = $Cert.PrivateKey.Decrypt($EncryptedBytes, $true)
$DecryptedPwd = [system.text.encoding]::UTF8.GetString($DecryptedBytes)
$SecurePassword  = convertto-securestring $DecryptedPwd -asplaintext -force
$Cred = new-object -typename System.Management.Automation.PSCredential -ArgumentList $User,$SecurePassword
##################################### CREDENTIAL ############################################################

Este código lo podemos usar de la siguiente manera:

Podemos usar la variable $DecryptedPwd para tener la contraseña en texto plano, por ejemplo se usa en autenticaciones básicas. También podemos usar el objeto de credenciales $CRED <PSCREDENTIAL> para usarlo en comandos de PowerShell directamente.

Como vemos, de este modo podemos usar las credenciales sin escribirlas en texto claro en los scripts o ficheros de configuración.

El certificado debemos mantenerlo de forma segura en el servidor que se va a usar y siempre podemos exportar la parte publica para encriptar las contraseñas en otros equipos, pero únicamente se podrán desencriptar donde este la parte privada instalada.

Con esto, puedes echarle imaginación y utilizarlo en muchos casos de uso distintos.