Page 1 of 1

RC4 Encryption

Posted: Fri Apr 09, 2010 7:27 am
by Frarth
I have not seen much about RC4 encryption on this forum, so I decided to post this example. I ported it from VB, optimized it for PB and added the DEK (default encryption key) feature. Might come in handy for someone.

Code: Select all

Structure AsciiType
  a.a[0]
EndStructure

#Encrypt_DEK_Size = 49

DataSection
  ; default encryption key
  _Encrypt_DEK:
  Data.a 16, 125, 235, 199, 173, 38, 21
  Data.a 41, 45, 61, 44, 7, 183, 47
  Data.a 18, 109, 71, 3, 19, 154, 78
  Data.a 106, 9, 122, 91, 8, 34, 11
  Data.a 82, 79, 25, 61, 158, 33, 111
  Data.a 8, 3, 26, 16, 233, 133, 17
  Data.a 26, 78, 253, 156, 227, 89, 43
EndDataSection

Procedure.s Encrypt_DEK()
  Protected Key.s{#Encrypt_DEK_Size}
  CopyMemory(?_Encrypt_DEK, @Key, SizeOf(Ascii) * #Encrypt_DEK_Size)
  ProcedureReturn Key
EndProcedure

Procedure.s Encrypt_RC4(Text.s, Key.s = "")
  Protected *TAscText.AsciiType
  Protected *TAscKey.AsciiType
  Protected tLen.i, kLen.i, i.i
  Protected Dim rb.a(255), a.a, b.a
  ; text length
  tLen = Len(Text)
  If tLen = 0
    ProcedureReturn ""
  EndIf
  ; key length
  If Len(Key) = 0
    Key = Encrypt_DEK()
  EndIf
  ; key length <= 256
  kLen = Len(Key)
  If kLen > 256
    kLen = 256
    Key = Left(Key, kLen)
  EndIf
  ; key address
  *TAscKey = @Key
  a = 0
  ; table
  For i = 0 To 255
    rb(i) = i
    a = (a + rb(i) + *TAscKey\a[i % kLen]) & $FF
    Swap rb(i), rb(a)
  Next
  ; text address
  *TAscText = @Text
  a = 0
  b = 0
  ; encrypt/decrypt
  For i = 0 To tLen - 1
    a = (a + 1) & $FF
    b = (b + rb(a)) & $FF
    Swap rb(a), rb(b)
    PokeA(*TAscText + i, *TAscText\a[i] ! rb((rb(a) + rb(b)) & $FF))
  Next
  ; return result
  ProcedureReturn Text
EndProcedure

; Example 1 (using default encryption key)
Define Text.s = Encrypt_RC4("Testing this algorithm")
Debug Text ;encrypted
Debug Encrypt_RC4(Text) ;decrypted

; Example 2 (using a password)
Define Password.s = "my password"
Define Text.s = Encrypt_RC4("Testing this algorithm", Password)
Debug Text ;encrypted
Debug Encrypt_RC4(Text, Password) ;decrypted

Re: RC4 Encryption

Posted: Fri Apr 09, 2010 7:45 am
by Frarth
A slightly adjusted version I use to encrypt/decrypt database records.

Code: Select all

Structure AsciiType
  a.a[0]
EndStructure

#Encrypt_DEK_Size = 49

DataSection
  ; default encryption key
  _Encrypt_DEK:
  Data.a 16, 125, 235, 199, 173, 38, 21
  Data.a 41, 45, 61, 44, 7, 183, 47
  Data.a 18, 109, 71, 3, 19, 154, 78
  Data.a 106, 9, 122, 91, 8, 34, 11
  Data.a 82, 79, 25, 61, 158, 33, 111
  Data.a 8, 3, 26, 16, 233, 133, 17
  Data.a 26, 78, 253, 156, 227, 89, 43
EndDataSection

Procedure.s Encrypt_DEK()
  Protected Key.s{#Encrypt_DEK_Size}
  CopyMemory(?_Encrypt_DEK, @Key, SizeOf(Ascii) * #Encrypt_DEK_Size)
  ProcedureReturn Key
EndProcedure

Procedure Encrypt_RC4(*Text, Key.s = "")
  Protected *TAscText.AsciiType
  Protected *TAscKey.AsciiType
  Protected tLen.i, kLen.i, i.i
  Protected Dim rb.a(255), a.a, b.a
  ; text length
  tLen = MemorySize(*Text)
  If tLen = 0
    ProcedureReturn
  EndIf
  ; key length
  If Len(Key) = 0
    Key = Encrypt_DEK()
  EndIf
  ; key length <= 256
  kLen = Len(Key)
  If kLen > 256
    kLen = 256
    Key = Left(Key, kLen)
  EndIf
  ; key address
  *TAscKey = @Key
  a = 0
  ; table
  For i = 0 To 255
    rb(i) = i
    a = (a + rb(i) + *TAscKey\a[i % kLen]) & $FF
    Swap rb(i), rb(a)
  Next
  ; text address
  *TAscText = *Text
  a = 0
  b = 0
  ; encrypt/decrypt
  For i = 0 To tLen - 1
    a = (a + 1) & $FF
    b = (b + rb(a)) & $FF
    Swap rb(a), rb(b)
    PokeA(*TAscText + i, *TAscText\a[i] ! rb((rb(a) + rb(b)) & $FF))
  Next
EndProcedure

; Example 1: encrypt record before writing it to file
CopyMemory(*Record, *Buffer, RecordSize)
Encrypt_RC4(*Buffer, EncryptionKey)
WriteData(Handle, *Buffer, RecordSize)

; Example 2: decrypt record after reading it from file
ReadData(Handle, *Buffer, RecordSize)
Encrypt_RC4(*Buffer, EncryptionKey)
CopyMemory(*Buffer, *Record, RecordSize)

Re: RC4 Encryption

Posted: Fri Apr 09, 2010 10:56 am
by UserOfPure
Frarth wrote:I have not seen much about RC4 encryption on this forum
You didn't search properly then. There's lots of discussions and code examples dealing with RC4.

Re: RC4 Encryption

Posted: Fri Apr 09, 2010 11:40 am
by Frarth
UserOfPure wrote:
Frarth wrote:I have not seen much about RC4 encryption on this forum
You didn't search properly then. There's lots of discussions and code examples dealing with RC4.
Like I said, I have not seen *much*. I searched for 'RC4 encryption' ('RC4' is too short apparently), and found these (which seem to be from the same code):
http://www.purebasic.fr/english/viewtop ... encryption
http://www.purebasic.fr/english/viewtop ... encryption
http://www.purebasic.fr/english/viewtop ... hlight=rc4

If I search the forum, I first look at the subject. If, in this example 'RC4' or something close to it is in the subject I know what I will get. If I look into all subjects with say 'encryption', I may spend an entire afternoon finding what I'm looking for.