質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
バッチファイル

バッチファイル(Batch File)は、Windowsのコマンドラインインタープリターによって複数のコマンドを実行させる事が出来るスクリプトファイルです。

Q&A

1回答

334閲覧

【バッチ】aiueoという文字列を数値化したい

shirai

総合スコア1290

バッチファイル

バッチファイル(Batch File)は、Windowsのコマンドラインインタープリターによって複数のコマンドを実行させる事が出来るスクリプトファイルです。

0グッド

0クリップ

投稿2024/04/13 19:09

実現したいこと

https://ja.wikipedia.org/wiki/Unicode%E4%B8%80%E8%A6%A7_0000-0FFF
unicode表によると「aiueo」は「0x0061006900750065006f」となるようですが
unicodeに則らなくても何進数であろうと構いませんのでバッチで数値化を実現したいです。
また、その逆も変換できるようにしたいです。

背景

特定の数名のユーザのためにバッチファイルを作成していますが、
その中にはDBへの接続情報が書かれてしまっています。
ユーザーには秘匿したいのですが、当然メモ帳等で開かれると一発アウトです。
最初はexe化することで回避を考えていましたが、諸事情によりNGになりました。

そこでハッシュ関数を利用する方法を思いつきました。
https://qiita.com/tsumita7/items/fe8ca1a77a3678d1717b
こちらのハッシュ関数を元に、以下のようなことを実現しようとしています。

  1. ユーザーにこのシステム専用のパスワードを作成してもらい尋ねる
  2. 教えていただいた私はその値を数値化する
  3. 数値化したパスワードをハッシュ関数に通す
  4. DBの接続生情報も同様に数値化し、3の結果と排他的論理和をとる。この値をバッチファイル内にベタ書きしてユーザーに渡す
  5. ユーザーはバッチ起動時に1のパスワードを入力する
  6. バッチの中でそのパスワードを数値化→ハッシュ化し、その値とベタ書きされた値と排他的論理和をとると「DBの接続生情報が数値化されたもの」が出てくるのでそれを文字列に戻してDBに接続する

前提

  • セキュリティの都合上windows標準に入っていない仕組みの利用は不可
    • バッチのライブラリ等もNG
    • python等ももちろんNG
    • 3rd partyツールもNG
    • powershellもNG
  • ユーザーがwiresharkやメモリ解析ツールで見れば生情報普通に見れるんじゃ・・・は気にしなくていい

試したこと

ひとまずChatGTPに頼ってみましたがうまく動きませんでした。

bat

1@echo off 2setlocal enabledelayedexpansion 3 4set "input=aiueo" 5set "output=" 6 7for /f "delims=" %%a in (`cmd /u /c "echo %input%"`) do set "input=%%a" 8 9for /l %%i in (0,1,100) do ( 10 set "char=!input:~%%i,1!" 11 if "!char!"=="" goto :done 12 for /f "tokens=2 delims=:=" %%A in (`chcp`) do ( 13 set /a "char_code=0x!char!" 14 set /a "char_code=char_code %% 0x10000" 15 set "output=!output! !char_code!" 16 ) 17) 18 19:done 20echo %output%

cmdというコマンドがないのは分かったのですがどう直せばいいのか分からず。。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

satokei

2024/04/13 19:43

> セキュリティの都合上windows標準に入っていない仕組みの利用は不可 > powershellもNG なぜ、PowerShell もダメなのでしょうか?
ikedas

2024/04/13 21:35 編集

バッチファイルの機能だけでご質問のようなことを実現するのは無理です。 PowerShellなどがOKなら望みが出てきますが、そうするとユーザがそれを使って他の何かよからぬことをしかねないという懸念があるのでしょう、一般職員が使う業務用のマシンでPowerShellなどを無効にしている事業所はよくありますね。 できないことではありますが一応書いておくと、おっしゃっている手順のうち「数値化」というのは特に必要ないです。コンピュータではすべてのデータを数値として扱い、文字列も例外ではありません。ハッシュ関数の適用から後の演算が処理の本質的な内容です。
pecmm

2024/04/14 00:53

自分で試したことないので分からないですが、ユーザ側バッチファイルは ①ユーザが入力したパスワードを一時ファイルに保存 ②`CertUtil -hashfile <一時ファイルのパス> <好きなハッシュアルゴリズム>` でハッシュ値生成 ③一時ファイルとかfor /f経由で②を取得してDB接続に使用 でいけるかもしれないですね
ikedas

2024/04/14 01:43

念のために書いておきますが、 参考にしたというサイトでは、certutil を使ってハッシュを出力しています。そこは理解されていますか。 certutil は一応Windowsに付属しているツールではありますが、これも「バッチのライブラリ等」に当たりますか。 もっとも、これを使っていいとなっても、排他的論理和の処理をする方法がないので、やはりだめですね。
otn

2024/04/14 13:47 編集

何が使えるか・使えないのの説明が不明瞭です。 ①「セキュリティの都合上windows標準に入っていない仕組みの利用は不可」が明瞭ですが、 ③「python等ももちろんNG」④「3rd partyツールもNG」は①で不可と言明済みですので、補足ですね(書かなくても同じ意味)。 これらと違い、⑤「powershellもNG」ですが、これはWindows標準ですが何故駄目なのか?? また、ikedasさんの確認事項にありますが、②「バッチのライブラリ等もNG」も意味不明です。 ③や④と同じく①の補足なので無視しして良いのか、⑤のように①と別の追加条件の何かを言わんとしているのか?要は、 「バッチの組み込み機能だけしか使えない(exeなど起動不可)」 「バッチからWindows標準の機能は呼び出して良い」 のどちらかの確認です。前者は非常に奇異なルールなのでまず無いとは思いますが、そうだとすると②は何を言いたいのか?後者なら①があるので、②の記述は不要。 ⑤ですが、もしかして「powershellの実行ポリシーの設定変更がNG」の間違いでは? もしそうなら、(勘違いしている人が多いのですが)実行ポリシーがデフォルトのままでもPowershellスクリプトは実行可能なので、Powershellを使う方法も検討してはどうでしょうか? あるいは、VBScriptという選択肢もあります。これはいずれ廃止という噂もありますが。OfficeもOKならVBAもあり。
satokei

2024/04/14 16:47 編集

> ユーザーがwiresharkやメモリ解析ツールで見れば生情報普通に見れるんじゃ・・・は気にしなくていい ユーザーがバッチファイルを改ざんして接続情報を取得する可能性も気にしないですか? 何をするバッチか分からないですが、DB側に適切な権限を与えたDBユーザーを用意した方がよさそう...
guest

回答1

0

文字列を文字コードを使って数値化するのはバッチ組み込み機能だけで可能なので、まあ、出来なくも無いので書いてみました。
難しいことは書いてないので、読めばわかるかと思います。
set /aの演算子の^ & >>などは文法上の特殊文字なので、引用符で囲む必要があることくらいが注意事項でしょうか。setlocal enabledelayedexpansionを知らなかった場合はこの際理解しましょ。

扱える数値は4バイト(符号付き32bit)なので、1文字を1バイト数値に変換すると、変数1つに4文字分入るので、例えばパスワード長さが16文字だと、4文字ずつ区切って数値化して、変数を4つ使って格納することになります。
95文字の表現には7bit要るので、詰め込んでも5文字は入りません。英数に限れば62文字なので6bitで済み、1変数に5文字詰め込むのは可能です。
サンプルでは、4文字ずつ切ったりつないだりするのは省略して4文字以下になった前提で書いてます。

なお、キーボードからIMEを使わず入力できる文字(いわゆるASCII文字)に限ると95個なので後半にif文を95個並べて文字コード化します。ただし、"とか^は単純に処理できないので普通に書くとエラーですが、パスワードとして許さない文字にすればいいかと。!も駄目かも。
(中略)の部分はASCII文字コード表を見て埋めましょう。

実際には、最初に1回だけやるXOR_VALを求める部分と、毎回実行するパスワード入力して以降の部分に分割して、それぞれ必要なサブルーチンをくっつけた2ファイルにします。

CMD

1@echo off 2setlocal enabledelayedexpansion 3set "DB_PASS=1qaz" 4set "USER_PASS=2wx" 5 6call :C4toINT "%DB_PASS%" 7set /a DB_VAL=RET 8call :C4toINT "%USER_PASS%" 9set /a USER_VAL=RET 10set /a "XOR_VAL=DB_VAL^USER_VAL" 11 12echo DB_VAL=%DB_VAL% 13echo USER_VAL=%USER_VAL% 14 15echo XOR_VAL=%XOR_VAL% 16 17rem ここまで前準備で、 18rem XOR_VALに排他的論理和結果が入っている前提で以下を実行 19 20set "INPUT_PASS=" 21set /p INPUT_PASS="ENTER USER PASS: " 22call :C4toINT "%INPUT_PASS%" 23set /a INPUT_VAL=RET 24 25set /a "FUKUGEN=XOR_VAL^INPUT_VAL" 26 27call :INTtoC4 "%FUKUGEN%" 28echo DB_PASS="%RET%" 29 30exit /b 31 32rem 以下サブルーチン 33:C4toINT 34set "STR=%~1" 35set RET=0 36for /l %%I in (0,1,3) do ( 37 call :ORD "!STR:~%%I,1!" 38 set /a RET=RET*256+C 39) 40exit /b 41 42:INTtoC4 43set VAL=%~1 44set "RET=" 45for /l %%I in (0,1,3) do ( 46 set /a "V=VAL&255" 47 call :CHR !V! 48 set "RET=!C!!RET!" 49 set /a "VAL>>=8" 50) 51exit /b 52 53:ORD 54if "%~1"=="" set /a C=0x00&exit /b 55if "%~1"==" " set /a C=0x20&exit /b 56:(中略) 57if "%~1"=="1" set /a C=0x31&exit /b 58if "%~1"=="2" set /a C=0x32&exit /b 59:(中略) 60if "%~1"=="a" set /a C=0x61&exit /b 61:(中略) 62if "%~1"=="q" set /a C=0x71&exit /b 63:(中略) 64if "%~1"=="w" set /a C=0x77&exit /b 65if "%~1"=="x" set /a C=0x78&exit /b 66if "%~1"=="y" set /a C=0x79&exit /b 67if "%~1"=="z" set /a C=0x7A&exit /b 68:(中略) 69if "%~1"=="~" set /a C=0x7E&exit /b 70exit /b 71 72:CHR 73if %1 EQU 0x00 set "C="&exit /b 74:(中略) 75if %1 EQU 0x31 set "C=1"&exit /b 76:(中略) 77if %1 EQU 0x61 set "C=a"&exit /b 78:(中略) 79if %1 EQU 0x71 set "C=q"&exit /b 80:(中略) 81if %1 EQU 0x7a set "C=z"&exit /b 82:(中略) 83exit /b

追記

コメントに書きましたが、「ぱっと見で分からない(ロジックを追ったり書き換えたりすればばれる)」程度でいいなら、外部コマンドが使える前提でbase64エンコードが楽です。

CMD

1作成: 2echo DBパスワード>tempfile1 3certutil -encode tempfile1 tempfile2 4を実行して、tempfile2の2行目を抜き出す 5 6実施: 7set ENCODED=上記の2行目 8echo %ENCODED%>tempfile1 9certutil -decode tempfile1 tempfile2 10set /p DECODED=<tempfile2 11del tempfile1 tempfile2

投稿2024/04/14 15:15

編集2024/04/15 00:34
otn

総合スコア84677

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ikedas

2024/04/14 22:55

xorができるのはわかりましたが、ハッシュ関数を使っていないので質問の要件を満たしていませんね。 setを使ってものすごーーーく頑張ればハッシュ関数ももしかして実装できたりするのかもしれませんが、仮にできたとしても実用に耐えないでしょうし。
otn

2024/04/15 00:07 編集

> そこでハッシュ関数を利用する方法を思いつきました。 と書かれている通り、ハッシュ化は問題に対しての解決策の1つの案なので、別の案と言うことです。 秘密情報(DBパスワード)とXORした結果だけが見えるので、特にハッシュ化の必要性は低いと思いますが、私が気づいてない理由があるのなら、サンプルコードが理解できれば、「ハッシュ化後の文字列(certutilの出力)を4文字ずつ区切って数値化する」という変更も簡単かと思います。前提次第ですが。 for /f "skip=1" %%A in ('certutil -hashfile パスワードが入ったファイル') do if not defined HASHED set HASHED=%%A > ハッシュ関数ももしかして実装できたりするのかもしれませんが、 自作する場合は、ハッシュ化の計算式は秘匿する必要が無いので、SHA1などメジャーな方法じゃなくて自作のもっと簡単な数式にすれば楽かと思います。
otn

2024/04/15 00:18

そもそも、バッチスクリプトにせよPowershellスクリプトにせよ、ユーザーが書き換えは可能なので、 DBパスワードを復元した次の行にそれを表示するコマンドを書けばばれます。 「ぱっと見でわからにないように」であれば、certurilでbase64エンコード・デコードだけでもいいのかも。⇒ それが良い気がしてきました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問