Unfortunately stepwise refinement just makes it a little harder each time, it simply takes longer messages or more traffic before the crack occurs. The fundamentals of this type of technique are weak in the presence of computers. Aim for a cipher that generates enciphered code the same length in bits as the message using a key of 64 to 256 independent bits.
The following demonstration cracker gets remarkably close to the correct key for such a short example message. Double the length of the message and it will find the 11 character key almost every time.
Code: Select all
'===================================================================
' Richard's demonstration key cracker for the EKV cipher
'===================================================================
Dim As String placode ' plain text
Dim As String keyCode ' key string
placode = "Kristian Virtanen, 2011, krisu.virtanen@gmail.coms"
keyCode = "Hello World"
'===================================================================
' Example Crypted Output: (tested with yabasic which i have in this machine)
' 5400, 11514, 11340, 12420, 12876, 3360, 8439, 12210, 3648, 9288
' 10500, 8208, 11716, 10476, 11880, 11211, 3520, 3828, 3552, 5700
' 5184, 4900, 3528, 4444, 3456, 11556, 12654, 3360, 10005, 12987
' 5244, 12744, 10500, 8208, 11716, 10476, 11880, 11211, 3520, 5568
' 11433, 12426, 10476, 10500, 7776, 4646, 10692, 11988, 12099
'===================================================================
Dim As Integer pcn = Len(placode) ' length of message
Dim Shared As Integer encicode(Len(placode)) ' encrypted text
Print
Print "length of plain text is ="; pcn
Print "length of key text is ="; Len(keycode)
Print
Dim As Integer ti ' plain text index
Dim As Integer ki = 0 ' key index
For ti = 0 To pcn - 1
encicode(ti) = placode[ti] * keycode[ki]
ki = ki + 1
If ki = Len(keyCode) Then ki = 0
Next ti
For ti = 0 To pcn-1
Print encicode(ti);
Next ti
Print : Print
'===================================================================
' demonstration of a crude key cracker
'===================================================================
' first the primes less than 256 are needed to factor the encicode
Const As Integer nprimes = 54
Dim Shared As Integer p, prime(1 To nprimes) =_
{ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29 _
, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71 _
, 73, 79, 83, 89, 97, 101, 103, 113, 107, 109 _
, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173 _
, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229 _
, 233, 239, 241, 251}
'-------------------------------------------------------------------
' characters in the key with prime ascii codes are insecure
Print "Prime characters in the key are weak ";
For p = 12 To 30
Print Chr(prime(p), 32);
Next p
Print
Print
'-------------------------------------------------------------------
' factorize and save the encicode
Dim Shared As Integer factors(pcn, 1 To nprimes)
For ti = 0 To pcn-1
Dim As Integer p = 1, i = encicode(ti)
Do
If (i Mod prime(p)) = 0 Then ' divisible by a prime
factors(ti, p) += 1 ' update record
i = i \ prime(p) ' try same again
Else
p = p + 1 ' advance to next bigger prime
End If
Loop Until (p > nprimes) Or (i = 1) ' done factorization
Next ti
'-------------------------------------------------------------------
' report the factorization for initial checking
For ti = 0 To pcn-1
Print Using "###### = "; encicode(ti);
For p = 1 To nprimes
If factors(ti, p) <> 0 Then
If factors(ti, p) = 1 Then
Print Using "### "; prime(p);
Else
Print Using "###^# "; prime(p); factors(ti, p);
End If
End If
Next p
Print
Next ti
Print
'-------------------------------------------------------------------
' do the keylength search
Dim As Integer minimum(1 To nprimes)
Dim As Integer keylength, i, j, k
Print "Length", "possible keys"
For keylength = 1 To pcn \ 2
Print keylength,
For i = 0 To keylength - 1 ' the first character of key
For p = 1 To nprimes
minimum(p) = 1000 ' initial guaranteed overestimate
Next p
For j = i To pcn - 1 Step keylength
For p = 1 To nprimes
If minimum(p) > factors(j, p) Then minimum(p) = factors(j, p)
Next p
Next j
' now we have another possible key character for this length key
j = 1
For p = 1 To nprimes
If minimum(p) > 0 Then j *= ( prime(p) ^ minimum(p) )
Next p
If (j < 32) Or (j > 126) Then j = 250 ' mask unprintables
Print Chr(j);
Next i
Print
Next keylength
'-------------------------------------------------------------------
Sleep ' end of crude cracker demo
'-------------------------------------------------------------------
For relatively long keys I would use a different technique based on the short random repetitions of characters in the plain text message.