This is an archived low-energy page for bots and other anonmyous visitors.
Please sign up if you are a human and want to interact.
in reply to CipherText
This is a note to anyone tempted to use this code.
Good encryption algorithms are surprisingly hard to write,
and very hard to verify. While rolling by hand is in
general not good practice, rolling your own encryption
algorithm is just plain stupid when so many good ones
are publically available.
The above is particularly bad. This is just an xor. The
only things notable about using xor is how often people
make that mistake, and how often cryptographers mention
that it is insecure. Pick up
Applied
Cryptography if you are curious how to crack it.
Needless to say, I voted -- on this node.
Re: Re (boo) 1: CipherText
by boo_radley (Parson) on Feb 08, 2001 at 14:05 UTC
|
Tilly's advice is very true -- some other programming community websites that I visit have "encryption" code sections. Most code offerings have one of three themes.
- Code that produces a cyphered text, takes negligible time to brute force.
- Code that produces a cyphered text, takes negligible time to brute force, won't decrypt own cypher.
- Caesar cyphers.
If you feel the need to try your hand at encryption, try one of the better documented, free (speech) algorithms : blowfish. Source code (in C and visual basic) is present, as well as a white paper describing the algoritm. There's even a set of test data to verify your implementation's correctness.
Again, writing good encryption is sticky stuff -- especially when TASMWTODI, including blowfish (and even an all-perl version). So, unless you have a wild encryption itch to scratch, I'd suggest one of these existing modules.
update : Level II encryption??? what's level I? ;-) | [reply] |
|
|
Level one is just a single XOR pass. Its somewhat useful for comparison purposes.
CipherText is targeting niche applications that require default HTTP transmission. Its output domain can be restricted, making it possible for use encrypting query string values in CGI applicatons. I have demonstrated a site wrapper that encrypts query values, embedding them into HTML links. When returned, the values must correspond to lookup data. Also thread authentication is made possible by changing the user key at each request.
Its amazing how much you can learn about syntax, implementing the same algorithm in several languages.
-Steeeeeve
| [reply] |
Re: Re (tilly) 1: CipherText
by Steeeeeve (Initiate) on Feb 08, 2001 at 22:30 UTC
|
Tilly: You need to study this algorithm more strenuously. Its a good one.
Don't feel too bad,, it fools almost everybody.
I'll be using it for a long time to come.
The second cipher is artwork. Very efficient at what it unknown does,, I spent a little CPU time to get something accomplished. One of the things about encryption is the possibilities for ciphertext messages and the domains of solutions. Working backwards, you can take ciphertext and look at how many possible key and message combinations would have to be tried knowing that the key has four known values in a domain, and that the message has just eight characters from another domain. Finding a ratio of something like N possible input messages exist based on a matrice of possibillites, gives a relative indication about the work done by the algorithm.
This is no simple XOR algorithm. It is a double cipher XOR algorithm that uses a sophisticated method to alter a given root key. From a given set of random values, there is no way of knowing the number of values inserted into the modified key.
/* ===================================================================
+===
--JavaScript Source File --
NAME: CipherText_II.js (Patent-Pending)
AUTHOR: Charles Prichard <greentv@paulbunyan.net>
For testing purposes only!!!
All other uses require writing!!!
REVISION/DATE: 02-05-01
PURPOSE: Text encryption.
NEW mask feature added to LEVEL_II cipher mode.
NEW user-friendly alphabetic key option not fully supported.
======================================================================
+ */
var USERMODE;
var MODE;
var r_key;
var att;
var offset;
var s_key;
var xString;
var xStr;
var _mask = new Array(9,29,19,6,13,5,24,25,19,7,21,9,3,30,10,15,19,18,
+22,19,8,18,30,0,11,2,27,27,15,27,0,15);
function newkey(){
USERMODE = "NUMERIC";
s_key = Make_shiftedKey();
offset = Math.floor(att/32);
}
function Encode(xString,cipher_key){
xStr = cipher(xString,cipher_key);
return xStr;
}
function Decode(xString,cipher_key){
offset = -offset;
xStr = cipher(xString,cipher_key);
return xStr;
}
function cipher(xString,cipher_key){
var xStr="";
var newkey;
var keylen = cipher_key.length;
var i = xString.length % keylen;
for(var cntr=0; cntr <= xString.length-1; cntr++){
if ((xString.charCodeAt(cntr) != 0x0d) && (xString.charCodeAt(cn
+tr) != 0x0a)){
if (USERMODE == "NUMERIC"){ newkey = cipher_key.charC
+odeAt(i) - 0x1f;}
else { if (USERMODE == "ALPHABETIC"){ newkey = cipher
+_key.charCodeAt(i) - 0x3f;}
}
xStr += String.fromCharCode(((newkey) ^ (xString.charCode
+At(cntr)-0x1f)+offset)+0x1f);
}
else if ((xString.charCodeAt(cntr) == 0x0d) || (xString.charCod
+eAt(cntr) == 0x0a)){
xStr += xString.charAt(cntr);
}
i++;
if (i == keylen){i = 0;}
}
return (xStr);
}
function setAttribute(){
att = 0x00;
var keyval;
for (var i=0; i <= r_key.length-1; i++){
keyval = r_key.charCodeAt(i) - 0x20;
att = att ^ keyval;
}
return att;
}
function Make_reverseKey(){
var _keyArray = new Array();
for(var i=0; i < r_key.length; i++){
_keyArray[i] = r_key.charAt(i);
}
_keyArray.reverse();
return _keyArray.join("");
}
function Make_shiftedKey(){
var shift = setAttribute();
s_key = Make_reverseKey();
if ((shift % 2) == 1){s_key = s_key.substring(1,s_key.length);}
else {s_key = s_key.substring(0,s_key.length-1);}
var element;
for (var i=0; i <= (shift - 1) % s_key.length; i++){
element = s_key.substring(0,1);
s_key = s_key.substring(1,s_key.length);
if (USERMODE = "NUMERIC"){
s_key = s_key + String.fromCharCode(_mask[element.char
+CodeAt(0) - 31] + 31);
}
else { if (USERMODE = "ALPHABETIC"){
s_key = s_key + String.fromCharCode(_mask[element.char
+CodeAt(0) - 63] + 63);}
}
}
return s_key;
}
I'm too tired at this time to elaborate everything. I'm claiming that its innovative to have taken a key attribute to articulate characteristics of the modified key, used in the second cipher pass. I have been using it for the desireable ability to restrict output domain. Recent analysis with matrices, mathematically revealed the benefit of an added masking feature. So I added it in an efficient manner and introduced a fair number of possible solutions to the matrix problem.
-Steeeeeve. | [reply] [d/l] |
|
|
| [reply] |
|
|
Its amazing how much syntax you can learn implementing the same algorithm in several languages. -Steeeeeve
| [reply] |
|
|
|
|
This is no simple XOR algorithm. It is a double cipher XOR algorithm that uses a sophisticated method to alter a given root key. From a given set of random values, there is no way of knowing the number of values inserted into the modified key.
I bet a spook could crack this with less than 1K of known plaintext. "double XOR" is
just reducible to XOR. And as tilly already said, XOR is "seekret decoder ring" stuff.
Your code is worthless to me, and worthless to anyone I have influence on. And that's a pretty large set of the audience here. Please stop bragging -- it merely makes you look more foolish on each round.
-- Randal L. Schwartz, Perl hacker
| [reply] |
|
|
Hey Merlyn.
I respect you. You know your stuff, no doubt about it. You even helped me get a better job, by turning me on to Perl with your book.
But hey! You're not supposed to say things like this! First off, you shouldn't be exerting your "influence" on others : let them make their own mistakes and learn from them,
just like you did I'm guessing. You say Steeeve is bragging, but you're claiming you have an influence on "a large set of the audience" at PerlMonks. Now who's bragging?
Ok this is a stupid post from me and I expect to be downvoted for it. Off-topic etc, but let's chill out a bit. And really, your post seems to me like you're asking anyone who likes you on PM to dislike and downvote Steeve, and I don't like that.
my 2 cents, which may or may not make any sense once I hit preview...
Azatoth a.k.a Captain Whiplash
Get YOUR PerlMonks Stagename here!
Want to speak like a Londoner?
| [reply] |
|
|
Dear Randall:
For ASCII compliant ciphertext just limit the key domain to 32 - 63 decimal. Of course you should then double the length of the keystring to increase the security to that provided using the 64 value domain.
To really claim that solving the algorithm is trivial, you will have to ultimately find someone who can do it. At present the world is working on it, largely because of the most disturbing way it has been implemented.
I'm going back to my VB. - SeeYa!
# CipherTextI.pm
#
# Charles Prichard 6-16-01
#
#
#################################################
package CipherTextI;
use strict;
use integer;
use bytes;
#################################################
# PUBLIC Subroutine #
#################################################
sub new($) {
my $class = shift;
my $self = {};
bless $self, ref $class || $class;
$self->{xString} = undef;
$self->{xStr} = undef;
$self->{R_KEY} = undef;
$self->{ATT} = undef;
$self->{S_KEY} = undef;
$self->{cipher_key} = undef;
$self->{RSORT} = [];
$self->init(@_);
return $self;
}
sub init($){
my $self = shift;
my ($params) = shift;
my @temp1 = split /\;/, $params;
my %params = ();
my @temp2=();
foreach my $x (@temp1){
@temp2 = split /\=/, $x;
$self->{$temp2[0]} = $temp2[1];
}
$self->{RSORT} = [3,28,7,5,39,62,34,32,56,18,17,6,29,49,63,45,13,1
+3,29,40,2,17,17,9,12,61,56,23,55,37,31,13,27,52,8,23,38,53,9,60,31,30
+,39,27,37,14,14,34,8,29,58,10,25,3,19,37,11,35,52,39,48,24,22,19];
$self->{S_KEY} = $self->Make_shiftedKeys();
return;
}
#################################################
# PUBLIC Subroutine #
#################################################
sub encipher($) {
my $self = shift;
my $MSG = shift;;
$MSG = $self->Encode($self->Encode($MSG,$self->{R_KEY}),$self->{S_
+KEY});
return $MSG;
}
#################################################
# PUBLIC Subroutine #
#################################################
sub decipher($) {
my $self = shift;
my $MSG = shift;;
$MSG = $self->Decode($self->Decode($MSG,$self->{S_KEY}),$self->{R_
+KEY});
return $MSG;
}
#################################################
# PRIVATE Subroutine #
#################################################
sub Make_shiftedKeys(){
my $self = shift;
my $shift = $self->setAttribute();
$self->{S_KEY} = $self->modifyKeys();
if (($shift % 2) == 1){$self->{S_KEY} = (substr($self->{S_KEY},1,(
+length $self->{S_KEY})));}
else {$self->{S_KEY} = (substr($self->{S_KEY},0,(length $self->{S_
+KEY}) - 1));}
my $key;
my $v;
for (my $i=0; $i <= ($shift - 1) % length $self->{S_KEY}; $i++){
+
my $key = substr($self->{S_KEY},0,1);
$v = ord($key) - 32;
$self->{S_KEY} = (substr($self->{S_KEY},1,(length $self->{
+S_KEY}) - 1));
$self->{S_KEY} .= ord($v ^ $self->{RSORT}[$v] + 32);
}
return $self->{S_KEY};
}
#################################################
# PRIVATE Subroutine #
#################################################
sub setAttribute(){
my $self = shift;
$self->{ATT} = 0x00;
for (my $i=0; $i < (length $self->{R_KEY}); $i++){
$self->{ATT} = $self->{ATT} ^ (ord(substr($self->{R_KEY},$i,1)
+) - 0x20);
}
return $self->{ATT};
}
#################################################
# PRIVATE Subroutine #
#################################################
sub modifyKeys(){
my $self = shift;
my S_KEY = "";
my $i, $x;
For $x = 1 To length($self->{R_KEY})
$i = ord(substr($self->{R_KEY}, $x, 1)) - 32
S_KEY = S_KEY + ord(($i ^ $self->{RSORT}[$i] ^ $self->{ATT}) +
+ 32)
Next x
return S_KEY;
}
#################################################
# PRIVATE Subroutine #
#################################################
sub Encode($$){
my $self = shift;
$self->{xString} = shift;
$self->{cipher_key} = shift;
$self->cipher();
return $self->{xStr};
}
#################################################
# PRIVATE Subroutine #
#################################################
sub Decode($$){
my $self = shift;
$self->{xString} = shift;
$self->{cipher_key} = shift;
$self->cipher();
return $self->{xStr};
}
#################################################
# PRIVATE Subroutine #
#################################################
sub cipher(){
my $self = shift;
$self->{xStr} = "";
my $keyval;
my $xch;
my @akeys = split "",$self->{cipher_key};
my $keylen = length $self->{cipher_key};
my $i = (length $self->{xString} % $keylen); # DATA DEPENDENT
+SHIFT
for(my $x=0; $x < length ($self->{xString}); $x++){
$keyval = ord($akeys[$i]) - 0x20;
$xch = ord(substr($self->{xString},$x,1));
if ($xch > 0x7f){ $xch = $xch - 0x21;}
if ($xch > 0x1f){
$xch = ($keyval ^ ($xch - 0x20)) + 0x20; # Apply ciph
+er
}
if ($xch > 0x7f){ $xch = $xch + 0x21;}
$self->{xStr} .= chr($xch);
$i++;
if ($i == $keylen){$i = 0;}
}
return;
}
1;
| [reply] [d/l] |
|
|
|
|
You are wrong. Not just slightly, but badly enough that I
could not in good conscience ever recommend you for any
programming job until I was convinced that you had learned
from your mistakes.
I leave it as an exercise for you to read Applied
Cryptography and figure out how to crack your own
scrambling algorithm. A hint. If you xor 20 times it is
the same as having done one xor. (Albeit against a
different key than any of your original 20.) So it does
not matter how well you have managed to confuse yourself
about what you have done, to an attacker this is an xor,
and if they get 2 messages written in English encrypted
this way, they are going to have little trouble reading
both of them.
Just because you don't see how they can do it, doesn't mean
that they can't. Or even that they will find it
particularly hard.
| [reply] |
|
|
True a simple XOR is weak. There is a 1:1 correspondence between the applied cipherbits and known plaintext values like spaces, periods and control characters. Knowing the plaintext at various period locations reveals the applied key value at the said locations. Its not hard to iterate through a message and piece together the key and the entire message attacking known plaintext values.
CipherText is a step beyond. Each message element is the result of two ciphers, not just one. The recurrence of a composite pattern is also diffused to N*(N-1) message elements. This is desireable to limit the amount of information available to frequency analysis thought necessary for an attack.
| [reply] |
|
|