You are not logged in.
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
From the little bit I've been able to test it so far, it works like a charm. Thanks for the help!
Offline
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
Thanks for the update! It is nice to know that ReNamer is being used in such sophisticated routines!
Offline
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.
$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
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
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
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
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