2012-04-10 2 views
1

Ich habe die Folowing JAVA Klasse einer XOR "Verschlüsselung" Klasse:JAVA Perl - Port XOR Verschlüssler Klasse

import java.io.PrintStream; 

public class Encryptor 
{ 

    private static final String m_strPrivateKey = "[email protected]$"; 

    public Encryptor() 
    { 
    } 

    public static String encrypt(String pass) 
    { 
     String strTarget = XORString(pass); 
     strTarget = StringToHex(strTarget); 
     return strTarget; 
    } 

    public static String decrypt(String pass) 
    { 
     String strTarget = HexToString(pass); 
     strTarget = XORString(strTarget); 
     return strTarget; 
    } 

    private static String GetKeyForLength(int nLength) 
    { 
     int nKeyLen = "[email protected]$".length(); 
     int nRepeats = nLength/nKeyLen + 1; 
     String strResult = ""; 
     for(int i = 0; i < nRepeats; i++) 
     { 
      strResult = strResult + "[email protected]$"; 
     } 

     return strResult.substring(0, nLength); 
    } 

    private static String HexToString(String str) 
    { 
     StringBuffer sb = new StringBuffer(); 
     char buffDigit[] = new char[4]; 
     buffDigit[0] = '0'; 
     buffDigit[1] = 'x'; 
     int length = str.length()/2; 
     byte bytes[] = new byte[length]; 
     for(int i = 0; i < length; i++) 
     { 
      buffDigit[2] = str.charAt(i * 2); 
      buffDigit[3] = str.charAt(i * 2 + 1); 
      Integer b = Integer.decode(new String(buffDigit)); 
      bytes[i] = (byte)b.intValue(); 
     } 

     return new String(bytes); 
    } 

    private static String XORString(String strTarget) 
    { 
     int nTargetLen = strTarget.length(); 
     String strPaddedKey = GetKeyForLength(nTargetLen); 
     String strResult = ""; 
     byte bytes[] = new byte[nTargetLen]; 
     for(int i = 0; i < nTargetLen; i++) 
     { 
      int b = strTarget.charAt(i)^strPaddedKey.charAt(i); 
      bytes[i] = (byte)b; 
     } 

     String result = new String(bytes); 
     return result; 
    } 

    private static String StringToHex(String strInput) 
    { 
     StringBuffer hex = new StringBuffer(); 
     int nLen = strInput.length(); 
     for(int i = 0; i < nLen; i++) 
     { 
      char ch = strInput.charAt(i); 
      int b = ch; 
      String hexStr = Integer.toHexString(b); 
      if(hexStr.length() == 1) 
      { 
       hex.append("0"); 
      } 
      hex.append(Integer.toHexString(b)); 
     } 

     return hex.toString(); 
    } 

    public static void main(String args[]) 
    { 
     if(args.length < 1) 
     { 
      System.err.println("Missing password!"); 
      System.exit(-1); 
     } 
     String pass = args[0]; 
     String pass2 = encrypt(pass); 
     System.out.println("Encrypted: " + pass2); 
     pass2 = decrypt(pass2); 
     System.out.println("Decrypted: " + pass2); 
     if(!pass.equals(pass2)) 
     { 
      System.out.println("Test Failed!"); 
      System.exit(-1); 
     } 
    } 
} 

ich zu portieren versucht es so Perl:

#!/usr/bin/perl 

use strict; 
use warnings; 

my $pass = shift || die "Missing password!\n"; 
my $pass2 = encrypt($pass); 
print "Encrypted: $pass2\n"; 
$pass2 = decrypt($pass2); 
print "Decrypted: $pass2\n"; 
if ($pass ne $pass2) { 
    print "Test Failed!\n"; 
    exit(-1); 
} 

sub encrypt { 
    my $pass = shift; 
    my $strTarget = XORString($pass); 
    $strTarget = StringToHex($strTarget); 
    return $strTarget; 
} 

sub decrypt { 
    my $pass = shift; 
    my $strTarget = HexToString($pass); 
    $strTarget = XORString($strTarget); 
    return $strTarget; 
} 

sub GetKeyForLength { 
    my $nLength = shift; 
    my $nKeyLen = length '[email protected]$'; 
    my $nRepeats = $nLength/$nKeyLen + 1; 
    my $strResult = '[email protected]$' x $nRepeats; 
    return substr $strResult, 0, $nLength; 
} 

sub HexToString { 
    my $str = shift; 
    my @bytes; 

    while ($str =~ s/^(..)//) { 
     my $b = eval("0x$1"); 
     push @bytes, chr sprintf("%d", $b); 
    } 
    return join "", @bytes; 
} 

sub XORString { 
    my $strTarget = shift; 
    my $nTargetLen = length $strTarget; 
    my $strPaddedKey = GetKeyForLength($nTargetLen); 
    my @bytes; 

    while ($strTarget) { 
     my $b = (chop $strTarget)^(chop $strPaddedKey); 
     unshift @bytes, $b; 
    } 
    return join "", @bytes; 
} 

sub StringToHex { 
    my $strInput = shift; 
    my $hex = ""; 
    for my $ch (split //, $strInput) { 
     $hex .= sprintf("%02x", ord $ch); 
    } 
    return $hex; 
} 

-Code scheint in Ordnung, aber das Problem ist, dass die JAVA-Klasse andere Ergebnisse als der Perl-Code ausgibt. In JAVA habe ich die Klartext-passsword

mentos

und als

& 4 codiert wird \ = 80CHB‘

Was soll ich tun zu meinem Perl-Skript, um das gleiche Ergebnis zu erhalten? Wo mache ich falsch?

Zwei weitere Beispiele: Klartext-

07ch4ssw3bby

ist codiert als:.

, # (0 \ = DM '@' 8WQ2T

(beachten Sie den Abstand nach @)

Letztes Beispiel Klartext:

conf75

codiert als:

& 7] P0G- #!

Vielen Dank für Ihre Hilfe!

mit diesem, dank Joni Salonen Ended up:

#!/usr/bin/perl 
# XOR password decoder 
# Greets: Joni Salonen @ stackoverflow.com 

$key = pack("H*","3cb37efae7f4f376ebbd76cd"); 

print "Enter string to decode: "; 
$str=<STDIN>;chomp $str; $str =~ s/\\//g; 
$dec = decode($str); 
print "Decoded string value: $dec\n"; 

sub decode{ #Sub to decode 
    @[email protected]_; 
    my $sqlstr = $subvar[0]; 
    $cipher = unpack("u", $sqlstr); 
    $plain = $cipher^$key; 
    return substr($plain, 0, length($cipher)); 
} 

Mein einziges und letztes Problem ist, dass, wenn ein „\“ gefunden wird (eigentlich „\\“, wie man den wahren Charakter entkommen), um die Entschlüsselung schief geht: - \ Beispiel codierte Zeichenfolge:

"(4 \\ 4XB \: 7" G @ "

(ich es mit doppelten Anführungszeichen entgangen, letzte Zeichen von th e-String ist ein Raum, sollte es zu

"ovFsB6mu"

aktualisieren dekodieren: dank Joni Salonen, habe ich 100% Arbeits Endfassung:

#!/usr/bin/perl 
# XOR password decoder 
# Greets: Joni Salonen @ stackoverflow.com 

$key = pack("H*","3cb37efae7f4f376ebbd76cd"); 

print "Enter string to decode: "; 
$str=<STDIN>;chomp $str; $str =~s/\\(.)/$1/g; 
$dec = decode($str); 
print "Decoded string value: $dec\n"; 

sub decode{ #Sub to decode 
    @[email protected]_; 
    my $sqlstr = $subvar[0]; 
    $cipher = unpack("u", $sqlstr); 
    $plain = $cipher^$key; 
    return substr($plain, 0, length($cipher)); 
} 
+1

Sie wäre besser dran, es wegzuwerfen und mit richtige Kryptographie, anstatt eine andere unsichere Version derselben unsicheren Sache zu erschaffen. – EJP

+0

"Hacken" entfernt nicht das letzte Zeichen der Zeichenfolge während der Java-Schleife von Anfang bis Ende? – rsp

+0

@EJP danke für den Tipp aber ist nicht für die Produktion, nur pädagogisch. – bsteo

Antwort

1

Ihre Verschlüsselungsschleife Überspringt das erste Zeichen von $strTarget, wenn es zufällig '0' ist. Man könnte es gegen einen leeren String vergleichen, anstatt zu prüfen, ob es „true“:

while ($strTarget ne '') { 
    my $b = (chop $strTarget)^(chop $strPaddedKey); 
    unshift @bytes, $b; 
} 

Update: Dieses Programm Saiten dechiffriert:

use feature ':5.10'; 

$key = pack("H*","3cb37efae7f4f376ebbd76cd"); 

say decrypt("&4\=80CHB'");   # mentos 
say decrypt(",#(0\=DM.'@ '8WQ2T"); # 07ch4ssw3bby 
say decrypt("&7]P0G-#!");   # conf75 

sub decrypt { 
    $in = shift; 
    $cipher = unpack("u", $in); 
    $plain = $cipher^$key; 
    return substr($plain, 0, length($cipher)); 
} 
+0

ausprobiert wird, und ich bekomme das gleiche Ergebnis: perl dec6admin.pl conf75 Verschlüsselt: 571f5e2a7747 Entschlüsselt: conf75 Ich sollte "& 7] P0G- # bekommen!" nicht "571f5e2a7747" – bsteo

+0

Scheint, ich bekomme HEX anstelle von String, sowieso wenn ich es enthexe, dasselbe schlechte Ergebnis. – bsteo

+0

Die beiden Programme geben '571f5e2a7747' aus. Woher bekommst du "& 7] P0G- #!"? – Joni