#11 2008-05-27 16:45

airjrdn
Member
Registered: 2007-07-14
Posts: 22

Re: Pascal script to XOR encrypt filenames?

Man, I really appreciate this, and just so you know, it's not for any "bad" purposes.  I'm wanting to mirror some of my files offsite and am using Synback to do the mirroring.  While it supports compressing & encrypting the files, it simply creates zip files, which don't support encrypting the filenames (at least the implementation of it Syncback uses), so this is my solution to hiding the actual contents of the zip files.

Offline

#12 2008-05-29 12:19

airjrdn
Member
Registered: 2007-07-14
Posts: 22

Re: Pascal script to XOR encrypt filenames?

From the little bit I've been able to test it so far, it works like a charm.  Thanks for the help!

Offline

#13 2009-01-26 23:38

airjrdn
Member
Registered: 2007-07-14
Posts: 22

Re: Pascal script to XOR encrypt filenames?

I wanted to write back in case someone else was interested in doing something similar.  I wanted to store files offsite, and mask both their contents, as well as their names (which may indicate their contents).  I accomplished this through a very simple batch file that you can drag and drop files onto.

ToDo:
   Compress files with a password (I chose RAR, partially because it can contain recovery record data)
   Encrypt filenames inside the compressed archive (just an extra level of security)
   Encrypt the archive filename (to further mask the contents, so it didn't just say Passwords.rar for instance)

Software used:
   ReNamer
   WinRAR
   custom batch file

Setup (only need to do once):
   Setup a profile in WinRAR
    - Right click a small file, select "Add to archive..."
    - Check "Put recovery record"
    - Switch to "Advanced" tab
    - Set a password, and check "Encrypt file names" box then click OK
    - Switch to "Files" tab
    - Select "Do not store paths" in "File paths" dropdown
    - Check "Put each file to separate archive"
    - Switch to "General" tab
    - Click "Profiles" button
    - Select "Save current settings to a new profile"
    - Click "Yes" on "Are you sure you want to store a password to the profile?" popup
    - Name the profile (I called mine Offsite Backups)
    - Check "Immediate execution"
    - Check "Add to context menu"
    - Click OK
    - Click OK on the main dialog box
    -
    - Your RAR will be built.  Double click it to test your password
Only proceed if that went ok

You can delete the RAR you just created

Create ReNamer presets
    - Use the code den4b wrote, put in your own Secret Key and save it as a preset called Encrypt
    - Change the Decode = False; line to Decode = True; and save that as a preset called Decrypt

Create a batch file with the following contents:

@echo off
set CDir=%~dp0
:loop
    if %1=="" goto end
    set FN=%1
    echo Creating "%CDir%%~nx1.rar" from %FN%
    "C:\Program Files\WinRAR\winrar.exe" a -cp"Offsite Backups" "%CDir%%~nx1.%~x1.rar" %FN%
    echo renaming "%CDir%%~n1.rar" to "%~nx1.rar"
    ren "%CDir%%~n1.rar" "%~nx1.rar"
    echo Encrypting name of "%~nx1.rar"
    "c:\ReNamer\Renamer.exe" /rename "Encrypt" "%CDir%%~nx1.rar"
    shift
    goto loop

:end

In the batch file...
    - Be sure to replace "Offsite Backups" with whatever you called your WinRAR profile
    - Be sure the paths to WinRAR and ReNamer are correct

That's it.  Assuming everything is correct, when you drag some files onto the batch file, it will RAR them using the profile you created and encrypt the RAR filenames so they are unreadable to anyone without this code and your Secret Key.

Note that I've only dragged local file and files from mapped network drives, not UNC paths.  I've not tested those yet.

One other thing...my RAR filename gets renamed to retain the original file extension.  That was on purpose so I could have the same filename w/multiple extensions...  So, password.txt and password.doc don't both become password.rar.

Reply if you have questions or improvement suggestions.

Thanks to den4b for his encrypt/decrypt script, and especially for all of his efforts on ReNamer!

Offline

#14 2009-02-01 13:26

den4b
Administrator
From: den4b.com
Registered: 2006-04-06
Posts: 3,440

Re: Pascal script to XOR encrypt filenames?

Thanks for the update! It is nice to know that ReNamer is being used in such sophisticated routines! smile

Offline

#15 2009-03-12 21:24

airjrdn
Member
Registered: 2007-07-14
Posts: 22

Re: Pascal script to XOR encrypt filenames?

I'd like to setup a php page that would get the key via a querystring variable, and display the unencrypted filename.  I've found a similar PHP function but am not having much luck w/the decrypt piece.  Could you possible lend some suggestions?  The php function I found is at http://www.jonasjohn.de/snippets/php/xor-encryption.htm

Edit - Here's my first attempt at translating the code to php.  Note that I'm really neither a Pascal, nor a PHP programmer. smile

$Key=$_GET['Key'];  // gets it from the url, ie; decrypt.php?Key=abc123

echo Decrypt('one_of_my_encrypted_filenames', $Key);

function XorEnDeCrypt($InputString, $Key)
{
    $IK = 1;
    $Result = '';
    for ($I = 1; $I <= strlen($InputString); $I++)
    {
        if ($IK > strlen($Key))
        {
            $IK = 1;
        }
        $Code = ord(substr($InputString, $I, 1)) xor ord(substr($Key, $IK, 1));
        $Result = $Result.chr($Code);
        $IK = $IK + 1;
    }
    return $Result;
}

function Decrypt($InputString, $Key)
{
    $Temp = $InputString;
    $Temp = str_replace('=', '/', $Temp);
    $Temp = base64_decode($Temp);
    $Temp = XorEnDeCrypt($Temp, $Key);
    $Result = utf8_decode($Temp);
    return $Result;
}

Edit2 - I think there's a difference between what PHP's base64_decode returns, and what the custom version within ReNamer returns.  Simply calling that function with a sample string returns different results in the two different apps/languages.

Last edited by airjrdn (2009-03-12 23:28)

Offline

#16 2009-03-14 16:07

den4b
Administrator
From: den4b.com
Registered: 2006-04-06
Posts: 3,440

Re: Pascal script to XOR encrypt filenames?

airjrdn wrote:

I think there's a difference between what PHP's base64_decode returns, and what the custom version within ReNamer returns.  Simply calling that function with a sample string returns different results in the two different apps/languages.

You got it right. PHP's base64_encode function uses MIME base 64 standard, while mine is a custom base 64 which does not comply with any particular standard, it simply encodes the data to base 64.

I guess there are 2 ways to make it work:
a) I can give you my base 64 code which you can convert to PHP;
b) Replace my custom base 64 code with MIME compatible one.

As you probably guessed already, the problem with option "A" is that you will have to recode the function yourself. But the problem with option "B" might be more serious - lost compatibility with text previously encoded by custom base 64.

What do you think?

Offline

#17 2009-03-14 16:19

airjrdn
Member
Registered: 2007-07-14
Posts: 22

Re: Pascal script to XOR encrypt filenames?

Let me try to do the conversion.  If I get it, I'll post the code here for everyone else to use as well.

Offline

#18 2009-03-14 16:27

den4b
Administrator
From: den4b.com
Registered: 2006-04-06
Posts: 3,440

Re: Pascal script to XOR encrypt filenames?

Ok, here you go. Base 64 code:

function Base64(const S: string; Decode: Boolean): string;
const
  Codes64 = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/';
var
  i: Integer;
  a: Integer;
  x: Integer;
  b: Integer;
begin
  Result := '';
  a := 0;
  b := 0;
  if Decode then
    begin
    for i := 1 to Length(s) do
      begin
      x := Pos(s[i], Codes64) - 1;
      if x >= 0 then
        begin
        b := b * 64 + x;
        a := a + 6;
        if a >= 8 then
          begin
          a := a - 8;
          x := b shr a;
          b := b mod (1 shl a);
          x := x mod 256;
          Result := Result + chr(x);
          end;
        end
      else Exit;
      end;
    end
  else
    begin
    for i := 1 to Length(s) do
      begin
      x := Ord(s[i]);
      b := b * 256 + x;
      a := a + 8;
      while a >= 6 do
        begin
        a := a - 6;
        x := b div (1 shl a);
        b := b mod (1 shl a);
        Result := Result + Codes64[x + 1];
        end;
      end;
    if a > 0 then
      begin
      x := b shl (6 - a);
      Result := Result + Codes64[x + 1];
      end;
    end
end;

P.S. I would recommend delphibasics.co.uk for information on things like mod, div, shl, shr, chr, etc.

Offline

#19 2009-03-14 19:30

den4b
Administrator
From: den4b.com
Registered: 2006-04-06
Posts: 3,440

Re: Pascal script to XOR encrypt filenames?

Right, below is a complete (without utf-8 decode) PHP code to reverse XOR-BASE64 encryption by ReNamer.

Points to consider:
* Indices of characters in Delphi strings are 1 based, while in PHP they are 0 based;
* In PHP you need to use "." (dot) to concatenate strings, because "+" will try to add the numerically.
* I would recommend delphibasics.co.uk for information on things like mod, div, shl, shr, chr, etc.
* In PHP you would need to use bitwise operations, for example XOR in Delphi and XOR in PHP between 2 integers stand for 2 different things.
* Do not mess up indices and boundaries for the iterators, as you did it in several parts of your code, for example: tiny things like "<=" instead of "<" in for loops would screw it all up.
* There is still Unicode vs ANSI problem, aka UTF-8 decode, etc.

function Decrypt($input, $key)
{
    $result = $input;
    $result = str_replace('=', '/', $result);
    $result = Base64Decode($result);
    $result = XorEnDeCrypt($result, $key);
    return $result;
}

function XorEnDeCrypt($input, $key)
{
    $IK = 0;
    $result = '';
    for ($I=0; $I<strlen($input); $I++)
    {
        if ($IK >= strlen($key)) $IK = 0;
        $ci = substr($input, $I, 1);
        $ck = substr($key, $IK, 1);
        $code = ord($ci) ^ ord($ck);
        $result .= chr($code);
        $IK++;
    }
    return $result;
}

function Base64Decode($input)
{
    $codes64 = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/';
    $result = '';
    $a = 0;
    $b = 0;
    for ($i=0; $i<strlen($input); $i++)
    {
        $c = substr($input, $i, 1);
        $x = strpos($codes64, $c);
        if ($x >= 0)
        {
            $b = $b * 64 + $x;
            $a = $a + 6;
            if ($a >= 8)
            {
                $a = $a - 8;
                $x = $b >> $a;
                $b = $b % (1 << $a);
                $x = $x % 256;
                $result .= chr($x);
            }
        }
    }
    return $result;
}

P.S. I will remove all redundant posts.

Offline

Board footer

Powered by FluxBB