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.