in reply to Re: password protect. (with James Bond encrypter/decrypter source)
in thread password protect Word, PDF, etc documents
...but your code has been broken. Below is a simple known plaintext
attack which "nearly" recovers the encryption key, given a block of
encrypted data and a few known plaintext bytes. It's generally not
difficult to get ahold of the known plaintexts, especially if you're
encrypting files like Word docs that have a fixed header.
You say your program was "based on the ABC1 idea." I don't know how close the resemblence is, but I'd like to point out that changing a cipher even slightly can destroy its security.
Here's the sample output. Notice that, for each key byte, the correct value is one of the given possibilities.
Secret key is 'Shaken' Guessing key bytes key byte 0 'S' : 10 key byte 1 '#' : 9 'h' : 10 key byte 2 '/' : 10 '3' : 9 'F' : 10 'N' : 9 'a' : 11 key byte 3 'k' : 11 'o' : 9 key byte 4 'F' : 9 '[' : 9 'e' : 11 'o' : 9 key byte 5 'a' : 9 'n' : 10And here's the code. It needs to know the block size and the length of the encryption key. That information might not be available, but it's easy enough to find by brute force.
Update: The DMCA can byte me. Show me where this cipher is used to "effectively control access to a copyrighted work." Cryptography is perfectly legal, and I'm getting tired of hearing from you fear-mongers.#!/usr/bin/perl use strict; use warnings; # this information is known to the attacker my ($ciphertext, $known_plaintext, $keylen); { # secret stuff in here my $key = "Shaken"; print "Secret key is '$key'\n"; $keylen = length($key); open F, $0 or die; # read test data from this script - why not? my $plaintext; read F, $plaintext, 1024 or die; close F; $known_plaintext = substr($plaintext, 0, 8); $ciphertext = encrypt_blk($plaintext, $key); } # secret stuff in here print "Guessing key bytes\n"; my $plain_bits = length($known_plaintext)*8; my $cipher_bits = length($ciphertext)*8 - 1; foreach my $keypos (0 .. $keylen-1) { print "key byte $keypos\n"; my $first = $keypos > 1 ? $keypos - 1 : $keylen + $keypos - 1; foreach my $keybyte (0x20 .. 0x7e) { my $keyval = ($keybyte >= 0x30 && $keybyte <= 0x39) ? $keybyte-0x2f : $keybyte+1; my $hits = 0; my $trials = 0; for (my $bitpos = $first; $bitpos < $plain_bits; $bitpos += $keyle +n) { my $pos = ($bitpos * $keyval) % $cipher_bits; $trials++; $hits++ if vec($known_plaintext,$bitpos,1) == vec($ciphertext,$p +os,1); } my $thresh = int($trials * .8); print "'",chr($keybyte),"' : $hits\n" if $hits > $thresh; } } sub encrypt_blk { my ($inblk, $key) = @_; my @key = map { (/\d/ ? $_ : ord) + 1 } split(//, $key); my $blkbytes = length($inblk); my $blkbits = $blkbytes * 8; my $outblk = "\0" x $blkbytes; my $used = "\0" x $blkbytes; my $keypos = 0; my $newpos; for (my $blkpos = 0; $blkpos < $blkbits; $blkpos++) { ++$keypos >= @key and $keypos = 0; $newpos = ($key[$keypos] * $blkpos) % ($blkbits - 1); while (vec($used, $newpos, 1)) { ++$newpos >= $blkbits and $newpos = 0; } vec($used, $newpos, 1) = 1; vec($outblk, $newpos, 1) = vec($inblk, $blkpos, 1); } return $outblk; } # encrypt_blk
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: I'm sorry, Mr. Bond
by gmpassos (Priest) on Jul 28, 2002 at 20:35 UTC | |
by no_slogan (Deacon) on Jul 28, 2002 at 22:49 UTC | |
A reply falls below the community's threshold of quality. You may see it by logging in. |
In Section
Seekers of Perl Wisdom