Czy mogę zamaskować tekst wejściowy w pliku bat?

102

Piszę plik wsadowy, aby wykonać inne programy. W takim przypadku muszę poprosić o hasło. Czy mogę w jakiś sposób zamaskować wprowadzany tekst? Nie muszę drukować znaków ******* zamiast znaków wejściowych. Wystarczające jest zachowanie monitu o hasło w Linuksie (nic nie drukuj podczas pisania).

@echo off
SET /P variable=Password : 
echo %variable%
Pause

Spowoduje to odczytanie danych wejściowych, ale nie mogę zamaskować tekstu przy użyciu tego podejścia.

Chathuranga Chandrasekara
źródło

Odpowiedzi:

50

Do XP i Server 2003 możesz użyć innego dołączonego narzędzia (VBScript) - dwa poniższe skrypty wykonają zadanie, które chcesz.

Po pierwsze getpwd.cmd:

@echo off
<nul: set /p passwd=Password: 
for /f "delims=" %%i in ('cscript /nologo getpwd.vbs') do set passwd=%%i
echo.

Następnie getpwd.vbs:

Set oScriptPW = CreateObject("ScriptPW.Password")
strPassword = oScriptPW.GetPassword()
Wscript.StdOut.WriteLine strPassword

Po getpwd.vbsprostu używa obiektu password do wprowadzenia hasła od użytkownika, a następnie wypisuje je na standardowe wyjście (następny akapit wyjaśnia, dlaczego nie pojawia się to w terminalu).

getpwd.cmdSkrypt poleceń jest nieco trudniejsze, ale to w zasadzie działa w następujący sposób.

Efektem "<nul: set /p passwd=Password: "polecenia jest wyświetlenie zachęty bez końcowego znaku nowej linii - jest to sprytny sposób na emulację "echo -n"polecenia z bashpowłoki. Ustawia passwdpusty łańcuch jako nieistotny efekt uboczny i nie czeka na dane wejściowe, ponieważ pobiera dane wejściowe z nul:urządzenia.

To "for /f "delims=" %%i in ('cscript /nologo getpwd.vbs') do set passwd=%%i"stwierdzenie jest najtrudniejsze. Uruchamia VBScript bez "reklam" Microsoftu, więc jedyną linią wyjściową jest hasło (z VBscript "Wscript.StdOut.WriteLine strPassword".

Ustawienie ograniczników na zero jest wymagane, aby przechwycić cały wiersz wejściowy ze spacjami, w przeciwnym razie otrzymasz tylko pierwsze słowo. Te "for ... do set ..."zestawy bitów passwdbyć rzeczywista moc hasło z VBScript.

Następnie wywołujemy echo pustej linii (aby zakończyć "Password: "linię), a hasło będzie w passwdzmiennej środowiskowej po uruchomieniu kodu.


Teraz, jak wspomniano, scriptpw.dlljest dostępny tylko do XP / 2003. Aby to naprawić, możesz po prostu skopiować scriptpw.dllplik z Windows\System32folderu systemu XP / 2003 do folderu Winnt\System32lub Windows\System32we własnym systemie. Po skopiowaniu biblioteki DLL należy ją zarejestrować, uruchamiając:

regsvr32 scriptpw.dll

Aby pomyślnie zarejestrować bibliotekę DLL w systemie Vista lub nowszym, będziesz potrzebować uprawnień administratora. Nie badałem legalności takiego posunięcia, więc jaskiniowiec.


Jeśli nie jesteś przesadnie zainteresowany próbami wyśledzenia i zarejestrowania starszych plików DLL (dla wygody lub ze względów prawnych), istnieje inny sposób. Późniejsze wersje systemu Windows (te, które nie mają wymaganej biblioteki DLL) powinny mieć dostępny program PowerShell.

I faktycznie, naprawdę powinieneś rozważyć uaktualnienie swoich skryptów, aby w pełni go używać, ponieważ jest to znacznie bardziej wydajny język skryptowy niż cmd.exe. Jeśli jednak chcesz zachować większość swojego kodu jako cmd.exeskrypty (na przykład jeśli masz dużo kodu, którego nie chcesz konwertować), możesz użyć tej samej sztuczki.

Najpierw zmodyfikuj cmdskrypt tak, aby wywoływał Powershell zamiast CScript:

@echo off
for /f "delims=" %%i in ('powershell -file getpwd.ps1') do set passwd=%%i

Skrypt Powershell jest równie prosty:

$password = Read-Host "Enter password" -AsSecureString
$password = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($password)
$password = [Runtime.InteropServices.Marshal]::PtrToStringAuto($password)
echo $password

chociaż z pewnym uporządkowaniem, aby uzyskać faktyczny tekst hasła.

Pamiętaj, że aby uruchomić lokalne niepodpisane skrypty Powershell na swoim komputerze, może być konieczne zmodyfikowanie zasad wykonywania z (drakońskiej, choć bardzo bezpiecznej) wartości domyślnej, na przykład:

set-executionpolicy remotesigned

z samego Powershell.

paxdiablo
źródło
2
Whoa, to <nul: set / p jest naprawdę fajne. Nie wiedziałem tego do tej pory :-). Ale VBScript nie działa dla mnie: Błąd wykonania Microsoft VBScript: składnik ActiveX nie może utworzyć obiektu: „ScriptPW.Password”. Windows 7 Beta x64 tutaj.
Joey
Co ciekawe, ma być dostępny od XP. Podejrzewam, że Win7 nie jest jeszcze skończony, jeśli tam nie działa (lub musisz wykonać inne sztuczki, aby zadziałał). Trochę badań pokazuje, dlaczego: zobacz moją aktualizację.
paxdiablo
2
Miły. Warto również zauważyć, że można zastąpić plik VBS dowolnym równoważnym językiem, który można wywołać z wiersza poleceń. Na przykład możesz zamienić sekcję cscript na: „python -c” z getpass import getpass; pwd = getpass (); print pwd; "'
Cerin
1
Korzystałem z tej drogi, gdy to pytanie było nowe - poniżej odpowiedziałem, jak to zrobić bez dodatkowych skryptów.
nieskrępowany
1
@Bill: Stąd moja sekcja zaczyna się od „Teraz niestety ...” :-) Jednak dodałem więcej opcji do odpowiedzi, aby miejmy nadzieję, że będzie ona lepsza. W szczególności użycie PowerShell zamiast scriptpw.dll.
paxdiablo
153

Tak - spóźniłem się 4 lata.

Ale znalazłem sposób na zrobienie tego w jednej linii bez konieczności tworzenia zewnętrznego skryptu; wywołując polecenia PowerShell z pliku wsadowego.

Dzięki TessellatingHeckler - bez wyprowadzania do pliku tekstowego (ustawiam polecenie PowerShell w zmiennej, ponieważ jest dość niechlujne w jednej długiej linii wewnątrz pętli for).

@echo off
set "psCommand=powershell -Command "$pword = read-host 'Enter Password' -AsSecureString ; ^
    $BSTR=[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($pword); ^
        [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)""
for /f "usebackq delims=" %%p in (`%psCommand%`) do set password=%%p
echo %password%

Pierwotnie napisałem go, aby wyprowadzić do pliku tekstowego, a następnie odczytać z tego pliku tekstowego. Ale powyższa metoda jest lepsza. W jednej niezwykle długiej, prawie niezrozumiałej linii:

@echo off
powershell -Command $pword = read-host "Enter password" -AsSecureString ; $BSTR=[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($pword) ; [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR) > .tmp.txt & set /p password=<.tmp.txt & del .tmp.txt
echo %password%

Wyjaśnię to - możesz to podzielić na kilka wierszy za pomocą daszka ^, co jest o wiele przyjemniejsze ...

@echo off
powershell -Command $pword = read-host "Enter password" -AsSecureString ; ^
    $BSTR=[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($pword) ; ^
        [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR) > .tmp.txt 
set /p password=<.tmp.txt & del .tmp.txt
echo %password%

W tym artykule wyjaśniono, co robią polecenia PowerShell; zasadniczo pobiera dane wejściowe za pomocą Read-Host -AsSecureString- następujące dwie linie konwertują ten bezpieczny ciąg z powrotem na zwykły tekst, a dane wyjściowe (hasło w postaci zwykłego tekstu) są następnie wysyłane do pliku tekstowego przy użyciu >.tmp.txt. Ten plik jest następnie wczytywany do zmiennej i usuwany.

nieskromny
źródło
5
Oryginalna odpowiedź była świetna, ale myślę, że teraz powinna być ostateczna
James Wiseman
30
To jest genialne. Ale sposób, w jaki zapisuje hasło w postaci zwykłego tekstu na dysku, sprawia, że ​​czuję się niekomfortowo. Unikaj robienia tego, robiąc to zamiast tego: for /f "usebackq tokens=*" %%p in (``powershell -Command "$pword = read-host 'Enter Password' -AsSecureString ; $BSTR=[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($pword); [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)"``) do set password=%%pi wtedy echo %password%. NB. Nie mogę uzyskać tego komentarza, aby poprawnie uciec przed znakami odwrotnymi - przed „powershell” i przed końcem „)” są dwa znaki grawerowane, ale powinien być jeden lewy apostrof.
TessellatingHeckler
1
@TessellatingHeckler Dobry pomysł, zaktualizowałem odpowiedź. Nieznacznie zmodyfikowana wersja Twojej sugestii. Dzięki.
Nieprzyjemne mięso
Czy można zatrzymać powtarzanie przez tę metodę znaku „*” (gwiazdki) przy każdym naciśnięciu klawisza? tj. nie chcę, aby obserwator wiedział, jak długie jest hasło.
Sam Hasler
1
@RegieBaguio Nie, będziesz potrzebować włączonej Powershell. Spójrz na czyste rozwiązanie wsadowe npocmaki poniżej. To dużo bardziej skomplikowane, ale powinno działać dla Ciebie.
nieszczęśnik
26

Czyste rozwiązanie wsadowe, które (ab) wykorzystuje XCOPYpolecenie i jego /P /Lprzełączniki znalezione tutaj (niektóre ulepszenia można znaleźć tutaj ):

:: Hidden.cmd
::Tom Lavedas, 02/05/2013, 02/20/2013
::Carlos, 02/22/2013
::https://groups.google.com/forum/#!topic/alt.msdos.batch.nt/f7mb_f99lYI


@Echo Off
:HInput
SetLocal EnableExtensions EnableDelayedExpansion
Set "FILE=%Temp%.\T"
Set "FILE=.\T"
Keys List >"%File%"
Set /P "=Hidden text ending with Ctrl-C?: " <Nul
Echo.
Set "HInput="
:HInput_
For /F "tokens=1* delims=?" %%A In (
 '"Xcopy /P /L "%FILE%" "%FILE%" 2>Nul"'
) Do (
  Set "Text=%%B"
  If Defined Text (
    Set "Char=!Text:~1,1!"
    Set "Intro=1"
    For /F delims^=^ eol^= %%Z in ("!Char!") Do Set "Intro=0"
    Rem If press Intro
    If 1 Equ !Intro! Goto :HInput#
    Set "HInput=!HInput!!Char!"
  )
)
Goto :HInput_
:HInput#
Echo(!HInput!
Goto :Eof 

1.2 Inny sposób oparty na komendzie zamiany

@Echo Off
SetLocal EnableExtensions EnableDelayedExpansion

Set /P "=Enter a Password:" < Nul
Call :PasswordInput
Echo(Your input was:!Line!

Goto :Eof

:PasswordInput
::Author: Carlos Montiers Aguilera
::Last updated: 20150401. Created: 20150401.
::Set in variable Line a input password
For /F skip^=1^ delims^=^ eol^= %%# in (
'"Echo(|Replace.exe "%~f0" . /U /W"') Do Set "CR=%%#"
For /F %%# In (
'"Prompt $H &For %%_ In (_) Do Rem"') Do Set "BS=%%#"
Set "Line="
:_PasswordInput_Kbd
Set "CHR=" & For /F skip^=1^ delims^=^ eol^= %%# in (
'Replace.exe "%~f0" . /U /W') Do Set "CHR=%%#"
If !CHR!==!CR! Echo(&Goto :Eof
If !CHR!==!BS! (If Defined Line (Set /P "=!BS! !BS!" <Nul
Set "Line=!Line:~0,-1!"
)
) Else (Set /P "=*" <Nul
If !CHR!==! (Set "Line=!Line!^!"
) Else Set "Line=!Line!!CHR!"
)
Goto :_PasswordInput_Kbd

2. Osoba przesyłająca hasło, która korzysta z wyskakującego okienka HTA . To jest plik hybrit .bat / jscript / mshta i powinien zostać zapisany jako .bat :

<!-- :
:: PasswordSubmitter.bat
@echo off
for /f "tokens=* delims=" %%p in ('mshta.exe "%~f0"') do (
    set "pass=%%p"
)

echo your password is %pass%
exit /b
-->

<html>
<head><title>Password submitter</title></head>
<body>

    <script language='javascript' >
        window.resizeTo(300,150);
        function entperPressed(e){
                if (e.keyCode == 13) {
                    pipePass();
                }
        }
        function pipePass() {
            var pass=document.getElementById('pass').value;
            var fso= new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1);
            close(fso.Write(pass));

        }
    </script>

    <input type='password' name='pass' size='15' onkeypress="return entperPressed(event)" ></input>
    <hr>
    <button onclick='pipePass()'>Submit</button>

</body>
</html>

3. Samodzielnie skompilowana hybryda .net .Again powinna zostać ponownie zapisana jako. .batW odróżnieniu od innych rozwiązań utworzy / skompiluje mały plik .exe, który zostanie wywołany (jeśli chcesz, możesz go usunąć). Wymaga również zainstalowanej platformy .net, ale to raczej nie jest problem:

@if (@X)==(@Y) @end /* JScript comment
@echo off
setlocal enableDelayedExpansion

for /f "tokens=* delims=" %%v in ('dir /b /s /a:-d  /o:-n "%SystemRoot%\Microsoft.NET\Framework\*jsc.exe"') do (
   set "jsc=%%v"
)

if not exist "%~n0.exe" (
    "%jsc%" /nologo /out:"%~n0.exe" "%~dpsfnx0"
)

for /f "tokens=* delims=" %%p in ('"%~n0.exe"') do (
    set "pass=%%p"
)

echo your password is !pass!

endlocal & exit /b %errorlevel%

*/



import System;



var pwd = "";
var key;

Console.Error.Write("Enter password: ");

        do {
           key = Console.ReadKey(true);

           if ( (key.KeyChar.ToString().charCodeAt(0)) >= 20 && (key.KeyChar.ToString().charCodeAt(0) <= 126) ) {
              pwd=pwd+(key.KeyChar.ToString());
              Console.Error.Write("*");
           }

           if ( key.Key == ConsoleKey.Backspace && pwd.Length > 0 ) {
               pwd=pwd.Remove(pwd.Length-1);
               Console.Error.Write("\b \b");
           }


        } while (key.Key != ConsoleKey.Enter);
        Console.Error.WriteLine();
        Console.WriteLine(pwd);
npocmaka
źródło
6
Czuję mrowienie, zwłaszcza przy hybrydzie!
Mark K Cowan,
2
To pierwsze rozwiązanie jest bardzo sprytne - fajne +1.
unclemeat
Metoda 2.1 oparta na komendzie zamiany pominie naciśnięcia klawiszy, jeśli piszesz szybko
Sam Hasler,
@SamHasler - tak, spróbuję to naprawić, chociaż nie mogłem odtworzyć problemu z wersją 2.1. Zaktualizowałem również aplikację HTA, aby sprawdzić, czy naciśnięto klawisz Enter.
npocmaka
1
@npocmaka ostatnia wersja metody 1.2 (ostatnia aktualizacja: 20150405) jest tutaj: consolesoft.com/batch/password_input/password_input.cmd
carlos
16

Prawdopodobnie po prostu zrobiłbym:

..
echo Before you enter your password, make sure no-one is looking!
set /P password=Password:  
cls
echo Thanks, got that.
.. 

Zostanie wyświetlony monit, a po jego wprowadzeniu ekran zostanie wyczyszczony.

Zwróć uwagę, że wprowadzone hasło zostanie zapisane w historii CMD, jeśli plik wsadowy zostanie wykonany z wiersza polecenia (Thanks @Mark K Cowan ).

Gdyby to nie wystarczyło, przełączyłbym się na Pythona lub napisałbym plik wykonywalny zamiast skryptu.

Wiem, że żadna z nich nie jest idealna, ale może jedna Ci wystarczy :)

Blorgbeard wyszedł
źródło
4
Zwróć uwagę, że wprowadzone hasło zostanie zapisane w historii CMD, jeśli plik wsadowy zostanie wykonany z wiersza polecenia. Bez głosów przeciw, ponieważ prawie powiedziałeś, że cmd jest niewłaściwym narzędziem do tego zadania.
Mark K Cowan,
Możesz uruchomić, doskey /reinstallaby wyczyścić poprzedni bufor poleceń natychmiast po cls, jeśli historia poleceń w konsoli nie jest dla Ciebie ważna.
RuntimeException
1
jeśli nie chcesz używać doskey / reinstaluj i wyczyść historię poleceń, inną opcją jest uruchomienie powyższego kodu w osobnym oknie terminala i natychmiastowe zamknięcie. Zwróć uwagę, że nadal nie zastępuje wpisanego ciągu znaków gwiazdkami. Powyższe rozwiązanie jest opcją, jeśli nie chcesz uruchamiać programu PowerShell. C:\>start "console" cmd /c ireadconsole.bat
RuntimeException
9

Możesz użyć procedury ReadFormattedLine dla wszelkiego rodzaju sformatowanych danych wejściowych. Na przykład poniższe polecenie odczytuje hasło składające się z 8 znaków, wyświetla gwiazdki na ekranie i kontynuuje automatycznie bez konieczności naciskania klawisza Enter:

call :ReadFormattedLine password="********" /M "Enter password (8 chars): "

Ten podprogram jest napisany w czystej Batch, więc nie wymaga żadnego dodatkowego programu i pozwala na kilka sformatowanych operacji wejściowych, takich jak odczyt samych liczb, zamiana liter na duże itp. Możesz pobrać podprogram ReadFormattedLine z Read a line o określonym formacie .


EDYCJA 2018-08-18 : Nowa metoda wprowadzania „niewidocznego” hasła

Polecenie FINDSTR ma dziwny błąd, który pojawia się, gdy to polecenie jest używane do wyświetlania znaków w kolorze ORAZ wyjście takiego polecenia jest przekierowywane do urządzenia CON. Szczegółowe informacje na temat używania polecenia FINDSTR do wyświetlania tekstu w kolorze można znaleźć w tym temacie .

Kiedy wynik tej postaci polecenia FINDSTR jest przekierowywany do CON, dzieje się coś dziwnego po wyświetleniu tekstu w żądanym kolorze: cały tekst po jego wyświetleniu jako „niewidoczne” znaki, chociaż dokładniejszy opis jest taki, że tekst jest wyjście jako czarny tekst na czarnym tle. Oryginalny tekst pojawi się, jeśli użyjesz polecenia KOLOR, aby zresetować kolory pierwszego planu i tła całego ekranu. Jednak gdy tekst jest „niewidoczny” możemy wykonać polecenie SET / P, więc wszystkie wprowadzone znaki nie pojawią się na ekranie.

@echo off
setlocal

set /P "=_" < NUL > "Enter password"
findstr /A:1E /V "^$" "Enter password" NUL > CON
del "Enter password"
set /P "password="
cls
color 07
echo The password read is: "%password%"
Aacini
źródło
5

inną alternatywą są moje narzędzia wiersza poleceń EditV32 (x86) lub EditV64 (x64). Na przykład:

editv32 -m -p "Password: " PWD

-m oznacza „zamaskowane wejście”, a -p to zachęta. Dane wejściowe użytkownika są przechowywane w zmiennej środowiskowej PWD. Możesz go zdobyć tutaj:

https://westmesatech.com/?page_id=19

Bill_Stewart
źródło
5
To nie jest jedyne rozwiązanie o zamkniętym kodzie źródłowym (system Windows to zamknięte źródło!). Oczywiście możesz go nie używać ...
Bill_Stewart
Jeśli przeszkadza Ci brak kodu źródłowego, zobacz moją drugą odpowiedź dotyczącą ReadLine.exe .
Bill_Stewart
Dobry! Licencja pozwala na korzystanie z niej. Ponadto łatwe do zintegrowania. Tylko po to, aby obsłużyć kod zakończenia 1. Błąd w wierszu poleceń, 2 wiersz wejściowy był pusty, 3 zmienna środowiskowa nie została zmieniona, 4 Program przerwany za pomocą Ctrl-C
James Jithin
Uwaga: narzędzia editenv32 / editenv64 i readline zostały zastąpione narzędziem open-source editenv .
Bill_Stewart
4

Jeśli przeszkadza Ci brak kodu źródłowego, mam inną alternatywę.

@echo off
for /f "delims=" %%p in ('ReadLine -h -p "Enter password: "') do set PWD=%%p
echo You entered: %PWD%

Możesz go pobrać z https://westmesatech.com/?page_id=49 . Zawiera kod źródłowy.

Bill_Stewart
źródło
Uwaga: narzędzia editenv32 / editenv64 i readline zostały zastąpione narzędziem open-source editenv .
Bill_Stewart
3

Jeśli masz zainstalowany Python, możesz użyć:

for /f "delims=" %%A in ('python -c "import getpass; print(getpass.getpass('Enter the CVS password: '));"') do @set CVSPASS=%%A
echo PASS: %CVSPASS%

wyjście:

Enter the CVS password:
PASS: 123
luteckiego
źródło
2

Skorzystałem z powyższego rozwiązania Blorgbearda, które moim zdaniem jest naprawdę świetne. Następnie ulepszyłem to w następujący sposób:

  1. Google dla ansicon
  2. Pobierz plik zip i przykładowy plik tekstowy.
  3. Zainstaluj (to znaczy skopiuj 2 pliki do systemu32)

Użyj tego w ten sposób:

@echo off
ansicon -p
set /p pwd=Password:ESC[0;37;47m
echo ESC[0m

Spowoduje to przełączenie konsoli na szary lub szary podczas wprowadzania hasła i przełączenie z powrotem, gdy skończysz. ESC powinien faktycznie być znakiem niedrukowalnym, który można skopiować z pobranego przykładowego pliku tekstowego (wygląda jak strzałka w lewo w Notatniku) do pliku wsadowego. Możesz użyć przykładowego pliku tekstowego, aby znaleźć kody dla wszystkich kombinacji kolorów.

Jeśli nie jesteś administratorem maszyny, prawdopodobnie będziesz w stanie zainstalować pliki w katalogu niesystemowym, a następnie musisz dołączyć katalog do PATH w swoim skrypcie przed wywołaniem programu i użyciem sekwencji ucieczki. Prawdopodobnie może to być nawet katalog bieżący, jeśli potrzebujesz pakietu dystrybucyjnego nieprzeznaczonego dla administratora, zawierającego tylko kilka plików.

marcingo
źródło
Nie mogę tego przetestować, ale spodziewałbym się, że wpisane hasło pojawi się później w historii cmd.
Mark K Cowan,
@MarkKCowan Dokładnie to się dzieje.
sjngm
1

utwórz plik wsadowy, który wywołuje ten wymagany dla niewidocznych znaków, a następnie utwórz skrót do wywoływanego pliku wsadowego.

kliknij prawym przyciskiem myszy

nieruchomości

zabarwienie

tekst == czarny

tło == czarny

zastosować

dobrze

nadzieja w ten sposób pomaga !!!!!!!!

cmd
źródło
przyjemne podejście do myślenia z boku, nawet jeśli nie zawsze jest to praktyczne w przypadku partii ze względu na konieczność wcześniejszego ustawienia środowiska. Och, poczekaj, może to zadziała: stackoverflow.com/a/14447306/14420 lub może stackoverflow.com/questions/4339649/ ...
Matt Wilkie
1

AKTUALIZACJA:
Dodałem dwie nowe metody, które zamiast używać cls do ukrywania danych wejściowych, tworzą nowe wyskakujące okienko z tylko jedną linią.

Wadą jest to, że jedna metoda (metoda 2) pozostawia śmieci w rejestrze - „Jeśli działa bez odpowiednich uprawnień”, a druga (metoda trzecia) dodaje do skryptu trochę śmieci. Nie trzeba dodawać, że można go łatwo zapisać w dowolnym pliku tmp i usunąć. Właśnie próbowałem wymyślić alternatywę.

Ograniczenie: hasło może być tylko alfanumeryczne - żadnych innych znaków!

@echo off
if "%1"=="method%choice%" goto :method%choice%
::::::::::::::::::
::Your code here::
::::::::::::::::::
cls
echo :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
echo ::::                   Batch script to prompt for password!                 :::
echo :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:choice
echo.
echo 1. First method
echo.
echo 2. Second method
echo.
echo 3. Third method
echo.
set/p choice=Choose a method: 
if "%choice%" gtr "3" echo. & echo invalid option & echo. & pause & goto choice

call :vars
    set options= %num%%smAlph%%cpAlph%
    set pwdLen=6

if "%choice%" == "1" (
    set /p=Password: <nul 
    for /l %%i in (1,1,%pwdLen%) do call :password
) else (
    start /wait cmd /c call "%~f0" method%choice%
    )

call :result%choice%


::just to see if it worked!
echo.
echo The Password you entered is: "%pwd%"&pause>nul

::::::::::::::::::
::More code here::
::::::::::::::::::
exit /b





:vars
set num=1234567890
set smAlph=abcdefghijklmnopqrstuvwxyz
set cpAlph=ABCDEFGHIJKLMNOPQRSTUVWXYZ
    set pwd=
goto :EOF


:method2
call :popUp
setx result %pwd% >nul
goto :EOF

:method3
call :popUp
    >> "%~f0" echo.
    >> "%~f0" echo :result%choice%
    >> "%~f0" echo set pwd=%pwd%
goto :EOF

:popUp
title Password
mode con lines=1 cols=30
color 5a
set /p=Password: <nul
for /l %%i in (1,1,%pwdLen%) do call :password
goto :EOF

:password
:: If you don't want case sensative remove "/cs" but remember to remove %cpAlph% from the %options%
choice /c %options% /n /cs >nul
    call SET pwd=%pwd%%%options:~%errorlevel%,1%%
    set /p =*<nul
GOTO :EOF


:result2
for /f "tokens=3" %%a in ('reg query hkcu\environment /v result') do set pwd=%%a
    setx result "" >nul
    reg delete hkcu\environment /v result /f >nul 2>&1
:result1
goto :EOF   
::You can delete from here whenever you want.

Update: Znalazłem posta sachadee do być doskonały , a ja po prostu dodał mój „pop-up” dziwactwo do niego.

@Echo Off  
  SetLocal EnableDelayedExpansion
  if "%1"==":HInput" goto :HInput
  set r=r%random%
  start /wait cmd /c call "%~f0" :HInput

For /f "tokens=2,13 delims=, " %%a in (
    'tasklist /v /fo csv /fi "imagename eq cmd.exe"
    ^|findstr /v "Windows\\system32\\cmd.exe"
    ^|findstr "set /p=%r%"'
     ) do (
        set pid=%%a
        set Line=%%b
        set Line=!Line:%r%=!
        set Line=!Line:~,-2!
        )       
taskkill /pid %pid:"=%>nul
  goto :HIEnd


  :HInput
  SetLocal DisableDelayedExpansion
  title Password
  mode con lines=2 cols=30

Echo Enter your Code :
   Set "Line="
   For /F %%# In (
   '"Prompt;$H&For %%# in (1) Do Rem"'
   ) Do Set "BS=%%#"

  :HILoop
   Set "Key="
   For /F "delims=" %%# In (
   'Xcopy /W "%~f0" "%~f0" 2^>Nul'
   ) Do If Not Defined Key Set "Key=%%#"
   Set "Key=%Key:~-1%"
   SetLocal EnableDelayedExpansion
   If Not Defined Key start /min cmd /k mode con lines=1 cols=14 ^&set/p %r%!Line!=&exit
  If %BS%==^%Key% (Set /P "=%BS% %BS%" <Nul
   Set "Key="
   If Defined Line Set "Line=!Line:~0,-1!"
   ) Else Set /P "=*" <Nul
   If Not Defined Line (EndLocal &Set "Line=%Key%"
   ) Else For /F delims^=^ eol^= %%# In (
   "!Line!") Do EndLocal &Set "Line=%%#%Key%"
  Goto :HILoop

  :HIEnd
   Echo(
Echo Your code is :  "!Line!"
   Pause
   Goto :Eof
Nieistotny
źródło
1

Napisałem program open source o nazwie, editenvktóry zastępuje moje starsze editv32/ editv64narzędzia:

https://github.com/Bill-Stewart/editenv

Opcja --maskinput( -m) [*] pozwala ukryć (zamaskować) wpisane wejście i ma konfigurowalny znak (domyślny znak to *); na przykład:

editenv -m -p "Password: " PWD

Opcja --prompt( -p) umożliwia określenie monitu o wprowadzenie danych. Powyższe wyświetli Password:monit i zaczeka, aż coś wprowadzisz. Wpisywane znaki pojawią się jako *. Naciśnięcie Ctrl+ Ckończy program z kodem zakończenia 1223.

Pobierz tutaj:

https://github.com/Bill-Stewart/editenv/releases

[*] Zauważ, że opcja --maskinput( -m) nie jest bezpieczna - wprowadzony ciąg jest wprowadzany jako zwykły tekst w środowisku. Ta funkcja ma na celu wyłącznie wygodę.

Bill_Stewart
źródło
-1
@echo off
color 0f
MODE CON COLS=132 LINES=50
:start
cls
choice /C ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!?.# /N /CS /M Please enter your password to continue. (Valid characters include all letters, numbers, and ! ? .) Press # to submit: 
SET ecode=%ERRORLEVEL%
IF %ecode% EQU 66 goto submit
IF %ecode% EQU 1 SET out=A
IF %ecode% EQU 2 SET out=B
IF %ecode% EQU 3 SET out=C
IF %ecode% EQU 4 SET out=D
IF %ecode% EQU 5 SET out=E
IF %ecode% EQU 6 SET out=F
IF %ecode% EQU 7 SET out=G
IF %ecode% EQU 8 SET out=H
IF %ecode% EQU 9 SET out=I
IF %ecode% EQU 10 SET out=J
IF %ecode% EQU 11 SET out=K
IF %ecode% EQU 12 SET out=L
IF %ecode% EQU 13 SET out=M
IF %ecode% EQU 14 SET out=N
IF %ecode% EQU 15 SET out=O
IF %ecode% EQU 16 SET out=P
IF %ecode% EQU 17 SET out=Q
IF %ecode% EQU 18 SET out=R
IF %ecode% EQU 19 SET out=S
IF %ecode% EQU 20 SET out=T
IF %ecode% EQU 21 SET out=U
IF %ecode% EQU 22 SET out=V
IF %ecode% EQU 23 SET out=W
IF %ecode% EQU 24 SET out=X
IF %ecode% EQU 25 SET out=Y
IF %ecode% EQU 26 SET out=Z
IF %ecode% EQU 27 SET out=a
IF %ecode% EQU 28 SET out=b
IF %ecode% EQU 29 SET out=c
IF %ecode% EQU 30 SET out=d
IF %ecode% EQU 31 SET out=e
IF %ecode% EQU 32 SET out=f
IF %ecode% EQU 33 SET out=g
IF %ecode% EQU 34 SET out=h
IF %ecode% EQU 35 SET out=i
IF %ecode% EQU 36 SET out=j
IF %ecode% EQU 37 SET out=k
IF %ecode% EQU 38 SET out=l
IF %ecode% EQU 39 SET out=m
IF %ecode% EQU 40 SET out=n
IF %ecode% EQU 41 SET out=o
IF %ecode% EQU 42 SET out=p
IF %ecode% EQU 43 SET out=q
IF %ecode% EQU 44 SET out=r
IF %ecode% EQU 45 SET out=s
IF %ecode% EQU 46 SET out=t
IF %ecode% EQU 47 SET out=u
IF %ecode% EQU 48 SET out=v
IF %ecode% EQU 49 SET out=w
IF %ecode% EQU 50 SET out=x
IF %ecode% EQU 51 SET out=y
IF %ecode% EQU 52 SET out=z
IF %ecode% EQU 53 SET out=0
IF %ecode% EQU 54 SET out=1
IF %ecode% EQU 55 SET out=2
IF %ecode% EQU 56 SET out=3
IF %ecode% EQU 57 SET out=4
IF %ecode% EQU 58 SET out=5
IF %ecode% EQU 59 SET out=6
IF %ecode% EQU 60 SET out=7
IF %ecode% EQU 61 SET out=8
IF %ecode% EQU 62 SET out=9
IF %ecode% EQU 63 SET out=!
IF %ecode% EQU 64 SET out=?
IF %ecode% EQU 65 SET out=.
SET code=%out%
SET show=*
:loop
cls
choice /C ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!?.# /N /CS /M Please enter your password to continue. (Valid characters include all letters, numbers, and ! ? .) Press # to submit: %code%
SET ecode=%ERRORLEVEL%
IF %ecode% EQU 66 goto submit
IF %ecode% EQU 1 SET out=A
IF %ecode% EQU 2 SET out=B
IF %ecode% EQU 3 SET out=C
IF %ecode% EQU 4 SET out=D
IF %ecode% EQU 5 SET out=E
IF %ecode% EQU 6 SET out=F
IF %ecode% EQU 7 SET out=G
IF %ecode% EQU 8 SET out=H
IF %ecode% EQU 9 SET out=I
IF %ecode% EQU 10 SET out=J
IF %ecode% EQU 11 SET out=K
IF %ecode% EQU 12 SET out=L
IF %ecode% EQU 13 SET out=M
IF %ecode% EQU 14 SET out=N
IF %ecode% EQU 15 SET out=O
IF %ecode% EQU 16 SET out=P
IF %ecode% EQU 17 SET out=Q
IF %ecode% EQU 18 SET out=R
IF %ecode% EQU 19 SET out=S
IF %ecode% EQU 20 SET out=T
IF %ecode% EQU 21 SET out=U
IF %ecode% EQU 22 SET out=V
IF %ecode% EQU 23 SET out=W
IF %ecode% EQU 24 SET out=X
IF %ecode% EQU 25 SET out=Y
IF %ecode% EQU 26 SET out=Z
IF %ecode% EQU 27 SET out=a
IF %ecode% EQU 28 SET out=b
IF %ecode% EQU 29 SET out=c
IF %ecode% EQU 30 SET out=d
IF %ecode% EQU 31 SET out=e
IF %ecode% EQU 32 SET out=f
IF %ecode% EQU 33 SET out=g
IF %ecode% EQU 34 SET out=h
IF %ecode% EQU 35 SET out=i
IF %ecode% EQU 36 SET out=j
IF %ecode% EQU 37 SET out=k
IF %ecode% EQU 38 SET out=l
IF %ecode% EQU 39 SET out=m
IF %ecode% EQU 40 SET out=n
IF %ecode% EQU 41 SET out=o
IF %ecode% EQU 42 SET out=p
IF %ecode% EQU 43 SET out=q
IF %ecode% EQU 44 SET out=r
IF %ecode% EQU 45 SET out=s
IF %ecode% EQU 46 SET out=t
IF %ecode% EQU 47 SET out=u
IF %ecode% EQU 48 SET out=v
IF %ecode% EQU 49 SET out=w
IF %ecode% EQU 50 SET out=x
IF %ecode% EQU 51 SET out=y
IF %ecode% EQU 52 SET out=z
IF %ecode% EQU 53 SET out=0
IF %ecode% EQU 54 SET out=1
IF %ecode% EQU 55 SET out=2
IF %ecode% EQU 56 SET out=3
IF %ecode% EQU 57 SET out=4
IF %ecode% EQU 58 SET out=5
IF %ecode% EQU 59 SET out=6
IF %ecode% EQU 60 SET out=7
IF %ecode% EQU 61 SET out=8
IF %ecode% EQU 62 SET out=9
IF %ecode% EQU 63 SET out=!
IF %ecode% EQU 64 SET out=?
IF %ecode% EQU 65 SET out=.
SET code=%code%%out%
SET show=%show%*
goto loop
:submit
cls
SET password=%code%
IF %password% EQU 0cZrocks! SET result=1
IF ELSE SET result=2
IF %result% EQU 1 echo password correct
IF %result% EQU 2 echo password incorrect
timeout /T 2 /NOBREAK >nul
cls
IF %result% EQU 1 goto end
IF ELSE goto start
:end
CODEMASTER
źródło
Nie wyjaśniłeś kodu, a tylko go skopiowałeś. Nie jest to dobry sposób, ponieważ musisz odświeżyć ekran, a hasło musi mieć długość x znaków.
Anic17
-1

Inną opcją, podobnie jak w przypadku Blorgbearda , jest użycie czegoś takiego:

SET /P pw=C:\^>

^Ucieka >tak szybka, że hasło będzie wyglądać standard cmd pocieszyć szybka.

nimbell
źródło
1
Pytanie nie dotyczy tego, jak ukryć / ukryć monit o hasło, ale zapobiec wyświetlaniu hasła podczas pisania. Więc to nie (próbuje) odpowiedzieć na pytanie.
Stephan
Ani odpowiedź, z którą się łączyłem (która w chwili pisania ma 13 głosów za). Moja odpowiedź jest tylko rozwinięciem tego tematu, ponieważ dla niektórych może to być użyteczna alternatywa (jak dla mnie Blogbeard wyszedł). (
Dodałbym
To nie jest dobra odpowiedź. Nie maskujesz ani nie ukrywasz hasła. Prosimy o komentarz, gdy masz dobre rozwiązanie lub odpowiedź.
Anic17
-3

Czytałem wszystkie niezgrabne rozwiązania w sieci o tym, jak maskować hasła w pliku wsadowym, te z rozwiązania hide.com, a nawet te, które sprawiają, że tekst i tło mają ten sam kolor. Rozwiązanie hide.com działa przyzwoicie, nie jest zbyt bezpieczne i nie działa w 64-bitowym systemie Windows. Tak czy inaczej, używając w 100% narzędzi firmy Microsoft, jest sposób!

Najpierw pozwól mi wyjaśnić moje zastosowanie. Mam około 20 stacji roboczych, które automatycznie logują się do systemu Windows. Mają na pulpicie jeden skrót - do aplikacji klinicznej. Maszyny są zablokowane, nie mogą kliknąć prawym przyciskiem myszy, nie mogą nic zrobić poza dostępem do jednego skrótu na pulpicie. Czasami konieczne jest, aby technik uruchomił niektóre aplikacje do debugowania, przeglądał eksplorator Windows i przeglądał pliki dziennika bez wylogowywania konta użytkownika autologu.

Oto, co zrobiłem.

Zrób to, jak chcesz, ale umieściłem moje dwa pliki wsadowe w udziale sieciowym, do którego ma dostęp zablokowany komputer.

Moje rozwiązanie wykorzystuje 1 główny składnik systemu Windows - runas. Umieść skrót na klientach do runas.bat, który zamierzasz utworzyć. Do Twojej wiadomości, na moich klientach zmieniłem nazwę skrótu, aby ułatwić przeglądanie i zmieniłem ikonę.

Będziesz musiał utworzyć dwa pliki wsadowe.

Nazwałam pliki wsadowe runas.bat i Debug Support.bat

runas.bat zawiera następujący kod:

cls
@echo off
TITLE CHECK CREDENTIALS 
goto menu

:menu
cls
echo.
echo           ....................................
echo            ~Written by Cajun Wonder 4/1/2010~
echo           ....................................
echo.
@set /p un=What is your domain username? 
if "%un%"=="PUT-YOUR-DOMAIN-USERNAME-HERE" goto debugsupport
if not "%un%"=="PUT-YOUR-DOMAIN-USERNAME-HERE" goto noaccess
echo.
:debugsupport
"%SYSTEMROOT%\system32\runas" /netonly /user:PUT-YOUR-DOMAIN-NAME-HERE\%un% "\\PUT-YOUR-NETWORK-SHARE-PATH-HERE\Debug Support.bat"
@echo ACCESS GRANTED! LAUNCHING THE DEBUG UTILITIES....
@ping -n 4 127.0.0.1 > NUL
goto quit
:noaccess
cls
@echo.
@echo.
@echo.
@echo.
@echo   \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
@echo   \\                                   \\
@echo   \\    Insufficient privileges         \\  
@echo   \\                                    \\
@echo   \\      Call Cajun Wonder             \\
@echo   \\                                    \\
@echo   \\              At                    \\
@echo   \\                                    \\
@echo   \\        555-555-5555                \\
@echo   \\                                    \\
@echo   \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
@ping -n 4 127.0.0.1 > NUL
goto quit
@pause
:quit
@exit

Możesz dodać tyle, jeśli "% un%", a jeśli nie "% un%" dla wszystkich użytkowników, którym chcesz dać dostęp. @Ping to mój sposób na zrobienie sekundowego timera.

Więc to załatwia pierwszy plik wsadowy - całkiem proste, prawda?

Oto kod dla Debug Support.bat:

cls
@echo off
TITLE SUPPORT UTILITIES
goto menu

:menu
cls
@echo %username%
echo.
echo           .....................................
echo            ~Written by Cajun Wonder 4/1/2010~
echo           .....................................
echo.
echo What do you want to do? 
echo.
echo [1]  Launch notepad
echo.

:choice
set /P C=[Option]? 
if "%C%"=="1" goto notepad
goto choice

:notepad
echo.
@echo starting notepad....
@ping -n 3 127.0.0.1 > NUL
start notepad
cls
goto menu

Nie jestem programistą i tak naprawdę dopiero rok temu zacząłem zajmować się pisaniem skryptów wsadowych, a ten sposób, w jaki odkryłem maskowanie hasła w pliku wsadowym, jest niesamowity!

Mam nadzieję, że usłyszę, że ktoś inny niż ja jest w stanie coś z tego zrobić!

CajunWonder
źródło