powershell-icon
uto
uto

Encrypt a string and convert it to JSON with PowerShell

November 20, 2020

background

This time, the purpose is to encrypt a string using PowerShell, output it to an external file (JSON in this case), and safely store data such as passwords. By using this JSON, you will be able to use the automatic login code you created last time more securely.

CryptJsonGenerator

By saving the above code in .ps1 format and running it, you can output the contents of the encrypted JSON file.

CryptJsonGeneratorDecoder

$user_name = Read-Host("登録するユーザー名を入力してください。")
$password = Read-Host("登録するパスワードを入力してください。")#暗号化されたuser_nameを生成$secure_user_name = ConvertTo-SecureString -string $user_name -AsPlainText -Force
$crypt_user_name = ConvertFrom-SecureString -SecureString $secure_user_name#暗号化されたパスワードを生成$secure_password = ConvertTo-SecureString -string $password -AsPlainText -Force
$crypt_password = ConvertFrom-SecureString -SecureString $secure_password#jsonに出力$json = @{user_name=$crypt_user_name; password=$crypt_password}
ConvertTo-Json $json | Out-File ".\User_Account.json" -Encoding utf8

Attention

The code we created this time uses user information as the Windows encryption key, and if the user changes, decryption will no longer be possible. Also, if you are signed in as the same user, anyone can decrypt it, so please be aware of that.

Appendix

Using this encryption and decryption, I would like to improve the automatic login script I created last time so that it does not require direct input of ID and password. So let's rewrite the code to read and decrypt the encrypted JSON file. The rewritten version is as follows.

#ユーザー情報読み込み[string]"ユーザー情報取得中"$json = ConvertFrom-Json -InputObject (Get-Content .\User_Account.json -Raw)
$crypt_user_name = $json.user_name
$crypt_password = $json.password
if(($crypt_user_name -eq $null) -or ($crypt_password -eq $null))
{
  $wsobj = new-object -comobject wscript.shell
  $wsobj.popup("ユーザーアカウントが読み込めません。`r`nUser_Account.jsonファイルを確認してください。")
  exit}
#復号化$secure_user_name = ConvertTo-SecureString -String $crypt_user_name
$secure_user_name = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($secure_user_name)
$user_name = [System.Runtime.InteropServices.Marshal]::PtrToStringBSTR($secure_user_name)

$secure_password = ConvertTo-SecureString -String $crypt_password
$secure_password = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($secure_password)
$password = [System.Runtime.InteropServices.Marshal]::PtrToStringBSTR($secure_password)

By inserting this into the first half of the previous script and storing the initial value NULL in the ID and password, it will read the JSON file in the same directory as the script file and log in. Please create the JSON file using CryptJsonGenerator in this article.

deliverables

ここで作成したコードで〇〇のコードを改変したのがこちらです。

$url = "URL"#目的のURL$login_url = "URL"#リダイレクトされたログインページのURL$user_name = $null#ログインID$password = $null#ログインパスワード$site_name = "Site_name"#ページのタイトルである場合が多い$user_name_id = "user_name_id"#HTMLのid入力欄のid$password_id = "password_id"#HTMLのpass入力欄のid$button_id = "login_button_id"#HTMLのログインボタンのid#上の項目は状況に合わせて変更必須#ユーザー情報読み込み[string]"ユーザー情報取得中"$json = ConvertFrom-Json -InputObject (Get-Content .\User_Account.json -Raw)
$crypt_user_name = $json.user_name
$crypt_password = $json.passwordif(($crypt_user_name -eq $null) -or ($crypt_password -eq $null))
{
  $wsobj = new-object -comobject wscript.shell
  $wsobj.popup("ユーザーアカウントが読み込めません。`r`nUser_Account.jsonファイルを確認してください。")
  exit}#復号化$secure_user_name = ConvertTo-SecureString -String $crypt_user_name
$secure_user_name = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($secure_user_name)
$user_name = [System.Runtime.InteropServices.Marshal]::PtrToStringBSTR($secure_user_name)

$secure_password = ConvertTo-SecureString -String $crypt_password
$secure_password = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($secure_password)
$password = [System.Runtime.InteropServices.Marshal]::PtrToStringBSTR($secure_password)#初期設定function OverrideMethod ([mshtml.HTMLDocumentClass]$Document) {
    $doc = $Document | Add-Member -MemberType ScriptMethod -Name "getElementById" -Value {
        param($Id)
        [System.__ComObject].InvokeMember(
            "getElementById",
            [System.Reflection.BindingFlags]::InvokeMethod,
            $null,
            $this,
            $Id
        ) | ? {$_ -ne [System.DBNull]::Value}
    } -Force -PassThru

    $doc | Add-Member -MemberType ScriptMethod -Name "getElementsByClassName" -Value {
        param($ClassName)
        [System.__ComObject].InvokeMember(
            "getElementsByClassName",
            [System.Reflection.BindingFlags]::InvokeMethod,
            $null,
            $this,
            $ClassName
        ) | ? {$_ -ne [System.DBNull]::Value}
    } -Force

    $doc | Add-Member -MemberType ScriptMethod -Name "getElementsByTagName" -Value {
        param($TagName)
        [System.__ComObject].InvokeMember(
            "getElementsByTagName",
            [System.Reflection.BindingFlags]::InvokeMethod,
            $null,
            $this,
            $TagName
        ) | ? {$_ -ne [System.DBNull]::Value}
    } -Force

    return $doc
}#初期設定終わり[string]"IE起動"$ie = New-Object -ComObject InternetExplorer.Application  # IE起動$ie.Visible = $false
$ie.Navigate($url,4)#ページを開く# ページが読み込まれるまで待機for ($i=0; $i -lt 100; $i++)
{
  if($ie.Busy -or $ie.readyState -ne 4)
  {
    break  }
  Start-Sleep -Milliseconds 10}

[string]"ログインページ取得中"#$ieの再設定$ie = $null
$jud = $false#ページ情報の取得for ($i=0; $i -lt 100; $i++)
{
  #シェルを取得  $shell = New-Object -ComObject Shell.Application
  #ieで開いているページ一覧を取得  $ie_list = @($shell.Windows() | where { $_.Name -match "Internet Explorer" })
  #ページタイトルを用いてオブジェクトを取得  $ie = @($ie_list | where { $_.LocationURL -match $login_url})
  if ($ie)
  {
    $jud = $true
    break  }elseif($ie_list | where { $_.LocationName -match $site_name})
  {
    [string]"ログイン不要`r`n処理終了"    exit  }
  Start-Sleep -Milliseconds 100}#エラーチェックif($jud -eq $false)
{
  $wsobj = new-object -comobject wscript.shell
  $wsobj.popup("自動ログインに失敗しました。`r`n手動でログインを行なってください。")
  exit}# ページが読み込まれるまで待機for ($i=0; $i -lt 100; $i++)
{
  if($ie.Busy -or $ie.readyState -ne 4)
  {
    Start-Sleep -Milliseconds 10  }else  {
    break  }
}

  [string]"ログイン実行中"  #最新のログイン画面を取得  $doc = OverrideMethod($ie[-1].Document)
$jud = $false#画面内に指定の要素があるかチェックfor ($i=0; $i -lt 100; $i++)
{
  $user_name_box=$doc.getElementById($user_name_id)
  $password_box=$doc.getElementById($password_id)
  $button = ($doc.getElementsByTagName("input") | where {$_.Value -eq $button_id})
  if ([string]::IsNullOrEmpty($user_name_box) -eq $false) 
  {
    if ([string]::IsNullOrEmpty($password_box) -eq $false) 
    {
      if ([string]::IsNullOrEmpty($button) -eq $false) 
      {
        $jud = $true
        break      }
    }
  }
  Start-Sleep -Milliseconds 100}#チェック内容に応じて処理を実行if($jud -eq $true)
{
  $user_name_box.value = $user_name
  $password_box.value = $password
  $button.click()
}else{
  $wsobj = new-object -comobject wscript.shell
  $wsobj.popup("自動ログインに失敗しました。`r`n手動でログインを行なってください。")
  exit}
[string]"処理終了"

There are almost no changes, but the login ID and password are set to NULL as default values, and code has been added to read and decrypt JSON and store it in the ID and password.brief Summary

I created this encryption because I had always thought that it was disgusting to type passwords etc. in the code. Although it can't be said to have strong security, I think it gives you a sense of security just because your passwords are not visible.

about us

Our company specialises in the development of advanced technologies for a wide range of industries. We use cutting-edge techniques and algorithms to create intelligent systems that can help businesses automate tasks, improve efficiency, and drive innovation.