Batch Variablen zu Binär konvertieren und XOR-Verknüpfen mit Powershell in Batch?

3 Antworten

Da Batch nicht mit allen ASCII Zeichen umgehen kann wird Dein Vorhaben problematisch .

XOR Ich bin ein String mit A ergibt ")a#(/a$(/a53(/&. Allein die Zeichen ")(/& würden einer Batch das "Genick" brechen. Das Zeichen  entspricht zudem jedem von Batch nicht decodierbaren Zeichen.

Da Batch selbst mit vielen Zeichen nicht Umgehen kann solltest Du nicht Versuchen irgendwelche Veschlüsselei zu versuchen . ("Geht nicht gibts nicht", aber der Aufwand wäre unvertretbar.)

Powerschell ist da wesentlich freundlicher:

XOR-String_Demo.ps1

$AusgangsString='Ich bin ein String';
  # A zu Charcode
$XORWert=[int][char]'A';
$XORWert
  #XOR des Strings  mit $XORWert
$XORString=([char[]][int[]]([char[]]$AusgangsString| %{[int][char]$_ -bxor $XORWert})) -join '';
$XORString;
$XORZurueck=([char[]][int[]]([char[]]$XORString| %{[int][char]$_ -bxor $XORWert})) -join '';
$XORZurueck;

Powerschell hat jedoch wesentlich effizientere Methoden zur Verschlüsselung von Daten bereits an Board.

Wenn Du schilderst, was Du vorhast können wir sicher eine effiziente Methode finden.

Woher ich das weiß:eigene Erfahrung – Ich mach das seit 30 Jahren
condoyi 
Fragesteller
 01.05.2020, 13:23

@Erzesel: Vielen Dank für deine Antwort.
Ich schildere kurz, was ich vorhabe. Ich habe zwei Binärdateien, aus deren Ende ich die jeweiligen Strings in die beiden Variablen %ORIG_varData1_ASCII% und %ORIG_varData2_ASCII% extrahiere. Dann habe ich noch eine Variable %varSchluessel_BIN%, der aus lauter 0en und 1en aussieht. Zum Beispiel: %varSchlussel_BIN%="0101110010" (kann aber auch anders sein).
Nachstehendes mache ich am Beispiel von %ORIG_varData1_ASCII% fest, für %ORIG_varData2_ASCII% wird/soll es identisch funktionieren. Ich möchte die Variable %ORIG_varData1_ASCII% in Binärformat konvertieren und in eine Variable %TMP_varData1_BIN% speichern (wirklich festhalten in der Variable) und im Anschluss mit %TMP_varData1_BIN% XOR %varSchlussel_BIN% das Ergebnis in einer neuen Variable speichern (wirklich speichern, z.B. als %NEW_varData1_BIN%). Diese neue Variable möchte ich dann im Anschluss zu ASCII wieder konvertieren und als Variable %NEW_varData1_ASCII% abspeichern. Hintergrund ist, dass ich mit diesem Konzept (irgendwann später) einen Code hätte, wo ich Binär zur ASCII konvertieren kann (und umgekehrt) und dann wieder leicht entschlüsseln (und verschlüsseln) kann, indem ich mit einem Schlüssel XORe.
Dass BATCH mit einigen ASCII-Kodierungen nicht umgehen kann, ist kein Problem, meine Beispiele von oben waren auch wirklich nur Beispiele. Mit Einfügen von PowerShell-Methoden geht mein geschildertes Vorhaben bestimmt einfach, aber ich weiß leider nicht, wie man vernünftig PowerShell in Batch-Dateien einfügt. Kannst du mir weiterhelfen?
"Powerschell hat jedoch wesentlich effizientere Methoden zur Verschlüsselung von Daten bereits an Board." - Das finde ich sehr interessant! Unabhängig von meinem geschildertem Anliegen: Kannst du vielleicht hierzu auch Empfehlungen aussprechen mit fertigem Code? Dann würde ich mir das Konzept genauer ansehen. Vielen Dank für deine Unterstützung.

0
Erzesel  02.05.2020, 09:09
@condoyi

Ich lese Deine Zeilen mir entzieht sich jedoch der Sinn.

Ich hat mit "schildern was Du vor hast" eigentlich eher etwas abstrakteres erwartet erwartet: Ich lese etwas aus einer Datei und verschlüssle dies und speichere es in eine neue Datei.

Was da Wann Warum mit welchen Variablen passiert ist Sache des Programmiers...

Irgendwie scheinst Du mit den Definitionen von Binär und ASCII nicht ganz klarzukommen. Erstmal enthalten alle Dateien binäre Daten. Wie diese Daten interpretiert werden hängt wie die Daten einer Datei vom öffnenden Programm bewertet werden.

Wird eine Datei als ASCII/Text-datei geöffnet werden alle Werte unter 32 als Steuerzeichen interpretiert. Die Werte bis 127 repräsentieren Buchstaben und Standardzeichen. Die übrigen 128 sind abhängig von der jeweiligen Zeichentabelle.

Wird eine Datei als Binärdatei geöffnet hat jedes Byte einfach nur einen Nummerischen Wert von 0 bis 255 . Wie das Programm derartige nackten Daten auswertet/darstellt.

Das Darstellungsformat der einzelnen Bytes hat nichts mit deren Werten zu tun, sondern dient ledig lich der Versinnbildlichung dieser. Normale Menschen verwenden dezimale Zahlen, Programmierer hexadecimale Zahlen. 0en und 1en werden eigentlich nur verwendet un normalen Menschen bitweise Verknüpfungen zu versinnbildlichen. Wenn Du irgendwo etwas wie: "110100" siehst ist dies erstmal lediglich ein String um diesen mit einem anderen Wert zb. XOR zu verknüpfen mus man ihn in seine numereische Entsprechung umwandel. Programme arbeiten mit Werten und nicht mit 0 und 1

Irgendwie hast Du Dich völlig in In den Definitionen verirrt.

(alle Beispiele in Powershell)

$BinaryString1='110100'
$Byte1=[Convert]::ToByte($BinaryString1,2) #Umwandeln in  ByteWert
'Der Bytewert von {0} = {1}' -f  $BinaryString1,$Byte1
$BinaryString2='11011'
$Byte2=[Convert]::ToByte($BinaryString2,2) #Umwandeln in  ByteWert
'Der Bytewert von {0} = {1}' -f  $BinaryString2,$Byte2
$Ergebnis=$Byte1 -bxor $Byte2  #Beide Werte xor-verknüpfen
$ErgbnisBinaryString=[Convert]::ToString($Ergebnis,2) #Umwandeln in  Binärstring
$ErgbnisHexString=[Convert]::ToString($Ergebnis,16) #Umwandeln in  Hexstring
$ErgebnisASCIIChar=[Char]$Ergebnis #Umwandeln in  ASCII-Zeichen
'{0} XOR {1} = {2} = Binary:{3} = Hexadecimal:{4} = ASCIICharakter:{5} ' -f  $Byte1,$Byte2,$Ergebnis,$ErgbnisBinaryString,$ErgbnisHexString,$ErgebnisASCIIChar

...egal in welcher Programmiersprache ..., wir arbeiten nicht mit 0 und 1... Bestenfalls kann man einen Wert als solche Anzeigen....

Wie bekommt man ein Powershellscript in eine Batchdatei?

PowershellHybrid-Demo.cmd

<# : BatchTeil
@echo off 
powershell -noprofile "iex (${%~f0} | out-string)"
exit /b
: end batch / begin powershell #>

$BinaryString1='110100'
$Byte1=[Convert]::ToByte($BinaryString1,2) #Umwandeln in  ByteWert
'Der Bytewert von {0} = {1}' -f  $BinaryString1,$Byte1
$BinaryString2='11011'
$Byte2=[Convert]::ToByte($BinaryString2,2) #Umwandeln in  ByteWert
'Der Bytewert von {0} = {1}' -f  $BinaryString2,$Byte2
$Ergebnis=$Byte1 -bxor $Byte2  #Beide Werte xor-verknüpfen
$ErgbnisBinaryString=[Convert]::ToString($Ergebnis,2) #Umwandeln in  Binärstring
$ErgbnisHexString=[Convert]::ToString($Ergebnis,16) #Umwandeln in  Binärstring
$ErgebnisASCIIChar=[Char]$Ergebnis
'{0} XOR {1} = {2} = Binary:{3} = Hexadecimal:{4} = ASCIICharakter:{5} ' -f  $Byte1,$Byte2,$Ergebnis,$ErgbnisBinaryString,$ErgbnisHexString,$ErgebnisASCIIChar
pause
1

Ich fand die Fragestellung witzig und hatte gerade Zeit. kopier mal folgende Zeilen in eine Datei xor.bat:

  • @echo off
  • set val1=%1
  • set val2=%2
  • set res=
  • echo calc [%val1%] XOR [%val2%]
  • :loop
  • set /A v1=%val1%/2
  • set /A v2=%val2%/2
  • set /A r1=%val1%-(2*%v1%)
  • set /A r2=%val2%-(2*%v2%)
  • echo [%val1%] = (2 * [%v1%]) + [%r1%]
  • echo [%val2%] = (2 * [%v2%]) + [%r2%]
  • IF "%r1%"=="%r2%" (
  •   set res=0%res%
  • ) ELSE (
  •   set res=1%res%
  • )
  • set val1=%v1%
  • set val2=%v2%
  • IF NOT "%val1%"=="0" GOTO :loop
  • IF NOT "%val2%"=="0" GOTO :loop
  • echo result=[%res%]
  • goto :EOF

Wenn Du die Datei mit zwei Zahlen als Übergabeparameter aufrufst, erhälst Du die binäre XOR Ausgabe. Zum Beispiel:

  • xor.bat 13 5
  • result=[1000]
condoyi 
Fragesteller
 01.05.2020, 02:17

Hi, danke für das batch Skript! Wie würde es denn aussehen, wenn in var1 und var2 keine Zahlen, sondern Strings sind wie bspw. var1="cjsjdfuwndb?!3#'&sbdj" und var2="lashsgds)(#-#!.374shdjdj"?Ich glaube mit Powershell den String zu Binär umzuwandeln und dann zu XOR'n ist einfacher, weiß aber nicht wie es geht. Kannst du mir weiterhelfen?

0
airfun  01.05.2020, 07:57
@condoyi

Die Übergabeparameter sind erst mal Strings. Wenn Du hier keine Ziffernfolgen sondern irgendwas eintippst, kann nichts sinnvolles rauskommen. Da ist es egal, ob in Batch-Skript, Powershell oder sonst was.

Oder geht Deine Frage dahin, dass Du die ASCII-Werte der Zeichenfolge aneinanderketten willst und diesen "Wert" dann XOR verknüpfen?

0
condoyi 
Fragesteller
 01.05.2020, 10:30
@airfun

Richtig! ASCII to Binary für jede variable und dann die beiden XOR'en. Die resultierende XOR'te Variable dann wieder konvertieren zu ASCII und in eine neue batch variable speichern. Mit Powershell gibt es da Befehle zu, allerdings fehlt mir das wissen, wie man Powershell in Batch Dateien vernünftig inkludiert und Outputs in Variablen speichert, etc. Kannst du mir helfen?

1
Erzesel  01.05.2020, 12:16

Warum Einfach wenn es auch kompliziert geht? 😅 dabei ist das Ergebniss noch nicht mal zu Dezimal zurückgewandelt...

Set /a hat einen XOR-Operateor! https://ss64.com/nt/set.html

@echo off
set "AusgangsWert=13"
echo AusgangsWert=%AusgangsWert%
set "XORWert=5"
set /a "res=AusgangsWert ^ XORWert"
echo %AusgangsWert% XOR %XORWert% = %res%


echo Gegenprobe:
set /a "AusgangsWert=res ^ XORWert"
echo %res% XOR %XORWert% = %AusgangsWert%


pause
exit /b

hier noch meine Pure-Batch Variante Zur sauberen Konvertierung von Decimal zu Binär und Zurück (ohne Deine Divissions-Orgien.

@echo off
setlocal EnableDelayedExpansion
chcp 65001 >nul & rem Umlaute  richtig darstellen.
:start


set "__Input="
set /p "__Input= Bitte  eine Zahl eingeben eingeben : "
  rem prüfen ob eine gültige Zahl eingegeben wurde
set /a "__dummy=__Input+0" 2>nul
if "%__dummy%" neq "%__Input%" (
    echo "%__Input%" ist keine zulässige Zahl ^( -2147483648..2147483647^)
    goto :Start
)
set "__Number=%__Input%"
set "__Binary="


  rem Speedoptimizing ... If  %__Number% positive the smallest  n can only be 0
if %__Number% geq 0 (
    for /l %%a in (1,1,31) do (
        set /a "Digit=__Number & 1,__Number>>=1" & set "__Binary=!Digit!!__Binary!" & rem Digit= n AND 1 , shift 1Bit right.
        if !__Number! equ 0 goto :break
)   ) 
  rem no else-Statement is needed here ...as the for-/l-Loop breaks to :break-Label
  rem the greatest negative n  is always -1
  rem in  this Fakt  fill the String with 31 leading 1 and cut 32Bit from behind...bye...
  rem while small Numbers this should faster then calculate each  Bit to the end....
for /l %%a in (1,1,31) do (
    set /a "Digit=__Number & 1,__Number>>=1" & set "__Binary=!Digit!!__Binary!"
    if !__number! equ -1 (
        set "__Binary=11111111111111111111111111111111!__Binary!"
        set "__Binary=!__Binary:~-32!"
        goto :break
)   )
:break
echo Decimal: %__Input% =  Binary: %__Binary%


echo  Wieder  zurückkonvertieren:
set "__dummyBin=%__Binary%"
set "__Decimal="
for /L %%i in (1,1,32) do (
    if defined __dummyBin (
        set /a "__Decimal=(__Decimal<<1)|!__dummyBin:~0,1!" & set "__dummyBin=!__dummyBin:~1!"
)   )


echo %__Decimal%
goto start
pause
1

Ich hatte etwas Zeit bei dem 💩Wetter...

Das Thema Verschlüsselung hat mich einfach interessiert , ergo habe ich etwas Experimentiert.

Die übergebenen Dateien werden mit einem Passwort verschlüsselt. Nicht mit dem Passwort selbst, sondern mit einem aus dem Passwort generierten 512Bit HashString. (das ist weit effizienter als 0 und 1.). Dieser Hat auch bei einem leeren Passwort 64 Zeichen.

Dieser String wird in einer Key-Datei abgelegt. Befindet diese sich bei der verschlüsselten Datei, kann diese ohne Passwortabfrage entschlüsselt werden.

Wird die Key-Datei gelöscht erfolgt vor dem Entschlüsseln eine Passwortabfrage.

Das Ganze funktioniert lediglich mit kleineren Dateien von maximal ein paar MB . Dann stößt Poweshell an die Grenzen. Über Geschwindigkeit muss man garnicht erst reden, etwa 5 Minuten für 30 MB 🥱😴. Bei einer kleinen Textdatei merkt man nichts davon.

XOR crypt File.pshybrid.cmd

<# : BatchTeil
@echo off 
chcp 65001 >nul
  rem wurde eine Datei  auf  die Batch gezogen? 
if "%~1"=="" (
    echo Zum Verschlüsseln ziehe eine beliebige Datei
      rem etwas Farbe in die Batch 
    powershell -c "Write-Host 'auf : ' -n ; Write-Host '%~nx0' -f cyan  "
    echo:
    powershell -c "Write-Host 'zum Entschlüsseln ziehe eine Datei mit der Endung : ' -n ; Write-Host '.encodet' -f magenta ; Write-Host 'auf : ' -n; Write-Host '%~nx0' -f cyan  "
    pause
    exit /b
)
powershell -noprofile "$InputfileFromBatch='%~f1' ;iex (${%~f0} | out-string)"
exit /b
: end batch / begin powershell #>


  #Funktionsdeklaration
function XOR-Data( $Data, $AssocValue ){
    $i=0;
    [char[]]$Data| %{
          #modulo des fortlaufenden Index (implizit erhöht) mit der Anzahl der Zeichen im Passwort
        $PWIndex=$i++ % $AssocValue.length;
        $_ -bxor $AssocValue[$PWIndex];
    };
};
function Hash-Encrypt($String='P@ssword'){
    
    [char[]][System.Security.Cryptography.HashAlgorithm]::Create('SHA512').ComputeHash([System.Text.Encoding]::ASCII.GetBytes($String))|%{
          #Nur ASCII-Zeichen von 32 bis 127
        $accu+=[char](([int]$_% (127-33) +33))
    }
    $accu
}
  #Ende Funktionsdeklaration  

<#............. Main .........#>
  
  #Dateiname aus der Aufrufzeile im Batchteil übernehmen
$InputFile=$InputFileFromBatch


if ((Get-Item $InputFile ).Extension -eq '.encoded') {
      #DateiNamen auflösen /generieren
    $FullName=(Get-Item $InputFile ).FullName
    $Split = $FullName.Split('\')
    $DirectoryPath=($Split|select -SkipLast 1) -join '\'
    $Name=$Split|select -Last 1
    $NonEncodedName=$Name -replace '.encoded',''
    $Split = $NonEncodedName.Split('.')
    $NonEncodedBaseName=($Split|select -SkipLast 1) -join '.'
    $NonEncodedExt= $NonEncodedName -replace "$NonEncodedBaseName.",''
    $OrignalFile="$DirectoryPath\$NonEncodedName"
    $OutputFile="$DirectoryPath\$NonEncodedBaseName.decoded.$NonEncodedExt"
    $KeyFile=$OrignalFile + '.key'
    $DecodeMode=$True


    Write-Host 'entschluessele : '
    Write-Host $InputFile -f yellow
    Write-Host 'nach:'
    write-Host $OutputFile -f yellow
    
    if ( Test-Path $KeyFile ){
        $encodedPassword=Get-Content $KeyFile
        Write-Host ('Keyfile: "{0}" gefunden' -f  $KeyFile) -f yellow
        Write-Host 'Autokey = ' -nonewline
        Write-Host $encodedPassword -f blue -nonewline
        Write-Host ' ...'
    }
    else {
        Write-Host ('...{0} nicht gefunden' -f $KeyFile) -f magenta
        $PasswordString=Read-Host 'Gib das Password ein';
          #aus dem Passwort einen 512Bit-Schüssel generieren
        $encodedPassword=Hash-Encrypt $PasswordString 
    }
}
else {
    $OutputFile=$InputFile + '.encoded'
    $KeyFile=$InputFile + '.key'
    Write-Host 'entschluessele : '
    Write-Host $InputFile -f yellow
    Write-Host 'nach:'
    write-Host $OutputFile -f yellow
    ''
    $PasswordString=Read-Host 'Bitte gib ein Passwort ein ';
      #aus dem Passwort einen 512Bit-Schüssel generieren
    $encodedPassword=Hash-Encrypt $PasswordString 
    $encodedPassword|Out-File $KeyFile
    Write-Host 'Autokey = ' -nonewline
    Write-Host $encodedPassword -f blue -nonewline
    Write-Host ' generiert ...'
    Write-Host ('Keyfile: "{0}" gespeichert...' -f  $KeyFile) -f yellow
    $DecodeMode=$False
}

  #als BinärDatei einlesen 
$BinaryInput=[System.IO.File]::ReadAllBytes($InputFile);
  #XOR der Daten mit $encodedPassword
$XOR_Binary=XOR-Data $BinaryInput $encodedPassword 
  #als BinärDatei schreiben 
[System.IO.File]::WriteAllBytes($OutputFile,$XOR_Binary);


if ($DecodeMode -and (Test-Path $OrignalFile ) ) {
     if ((Get-FileHash $OutputFile).Hash -eq  (Get-FileHash $OrignalFile).Hash){
        Write-Host "erfolgreich decodiert...." -f Green
    }
    else {
        Write-Host "Fehler  beim decodieren....(falsches Passwort?)" -f Red
     }
}

pause
Woher ich das weiß:eigene Erfahrung – Ich mach das seit 30 Jahren