Image and Texture crypter - simplest use + AES

Share your advanced PureBasic knowledge/code with the community.
User avatar
Saki
Addict
Addict
Posts: 830
Joined: Sun Apr 05, 2020 11:28 am
Location: Pandora

Image and Texture crypter - simplest use + AES

Post by Saki »

Since there are always inquiries about this, here two simplest to use solutions.

This solutions works 'on place', it can encrypt images and textures very fast in itself,
without the need of temporary images or buffers.

On all you can set a password or not.

You can only compress encrypted images lossless, e.g. save as PNG, not as JPEG,
otherwise the content of the encrypted images will be destroyed.

Hints:
You can also use the BaseU_BF and all Data_Codes_BF for this purpose.

Have fun

Code: Select all

EnableExplicit

; Hidde your images and textures - Simple 'on place' image crypter

Procedure EncryptImageSimple_BF(image_ID, seed=0)
  Protected i : RandomSeed(seed) ; By Saki
  If Not IsImage(image_ID) Or Not StartDrawing(ImageOutput(image_ID)) : ProcedureReturn 0 : EndIf
  Protected image_length=DrawingBufferPitch()*ImageHeight(image_ID)-1
  Protected *buffer=DrawingBuffer() : StopDrawing()
  For i=0 To image_length : PokeA(*buffer+i, PeekA(*buffer+i)+Random(255)) : Next : ProcedureReturn 1
EndProcedure

Procedure DecryptImageSimple_BF(image_ID, seed=0)
  Protected i : RandomSeed(seed) ; By Saki
  If Not IsImage(image_ID) Or Not StartDrawing(ImageOutput(image_ID)) : ProcedureReturn 0 : EndIf
  Protected image_length=DrawingBufferPitch()*ImageHeight(image_ID)-1
  Protected *buffer=DrawingBuffer() : StopDrawing()
  For i=0 To image_length : PokeA(*buffer+i, PeekA(*buffer+i)-Random(255)) : Next : ProcedureReturn 1
EndProcedure

; ######## Get the result ########

UsePNGImageDecoder() : UseJPEGImageDecoder() : UseTIFFImageDecoder()

Define path$=OpenFileRequester("Select a image", "", "", 0) : If path$="" : End : EndIf

Define image_ID=LoadImage(#PB_Any, path$)

ResizeImage(image_ID, 300, 300)

Define window_ID=OpenWindow(#PB_Any, 0, 0, 660, 340, "Left=encrypted  - Right=decrypted", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)

; #### Encrypt a image ####
Define seed_as_password=1000
EncryptImageSimple_BF(image_ID, seed_as_password)
Define image_gadget_ID=ImageGadget(#PB_Any, 20, 20, 0, 0, ImageID(image_ID))

; #### Decrypt a image ####
Define seed_as_password=1000
DecryptImageSimple_BF(image_ID, seed_as_password)
Define image_gadget_1_ID=ImageGadget(#PB_Any, 340, 20, 0, 0, ImageID(image_ID))

Repeat : Until WaitWindowEvent()=#PB_Event_CloseWindow

AES based

Code: Select all

EnableExplicit
; Hidde your images and textures - Simple 'on place' AES based image crypter

Procedure EncryptImageSimple_BF(image_ID, password$="")
  Protected i, ii, i1, depth : UseMD5Fingerprint() ; By Saki
  Protected fixed$=StringFingerprint(password$+"%$(s4DäÖÄö", #PB_Cipher_MD5) : Dim register.q(1)
  Repeat ; 16 Bytes
    PokeA(@register(0)+i, Val("$"+PeekS(@fixed$+ii, 2))) : ii+SizeOf(character)<<1 : i+1 ; Create a key
  Until ii=StringByteLength(fixed$) : i=0 : ii=0
  If Not IsImage(image_ID) Or Not StartDrawing(ImageOutput(image_ID)) : ProcedureReturn 0 : EndIf
  Protected image_length=DrawingBufferPitch()*ImageHeight(image_ID)-1
  Protected *buffer=DrawingBuffer() : StopDrawing()
  For i=0 To image_length
    Repeat
      If Not i1 : AESEncoder(@register(0), @register(0), 16, @register(0), 128, 0, #PB_Cipher_ECB) : EndIf
      depth=PeekA(@register(0)+i1) : i1+1 : If i1>15 : i1=0 : EndIf
    Until depth 
  PokeA(*buffer+i, PeekA(*buffer+i)+depth) : Next : ProcedureReturn 1
EndProcedure

Procedure DecryptImageSimple_BF(image_ID, password$="")
  Protected i, ii, i1, depth : UseMD5Fingerprint() ; By Saki
  Protected fixed$=StringFingerprint(password$+"%$(s4DäÖÄö", #PB_Cipher_MD5) : Dim register.q(1)
  Repeat ; 16 Bytes
    PokeA(@register(0)+i, Val("$"+PeekS(@fixed$+ii, 2))) : ii+SizeOf(character)<<1 : i+1 ; Create a key
  Until ii=StringByteLength(fixed$) : i=0 : ii=0
  If Not IsImage(image_ID) Or Not StartDrawing(ImageOutput(image_ID)) : ProcedureReturn 0 : EndIf
  Protected image_length=DrawingBufferPitch()*ImageHeight(image_ID)-1
  Protected *buffer=DrawingBuffer() : StopDrawing()
  For i=0 To image_length
    Repeat
      If Not i1 : AESEncoder(@register(0), @register(0), 16, @register(0), 128, 0, #PB_Cipher_ECB) : EndIf
      depth=PeekA(@register(0)+i1) : i1+1 : If i1>15 : i1=0 : EndIf
    Until depth 
  PokeA(*buffer+i, PeekA(*buffer+i)-depth) : Next : ProcedureReturn 1
EndProcedure

; ######## Get the result ########

UsePNGImageDecoder() : UseJPEGImageDecoder() : UseTIFFImageDecoder()

Define path$=OpenFileRequester("Select a image", "", "", 0) : If path$="" : End : EndIf

Define image_ID=LoadImage(#PB_Any, path$)

ResizeImage(image_ID, 300, 300)

Define window_ID=OpenWindow(#PB_Any, 0, 0, 660, 340, "Left=encrypted  - Right=decrypted", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)

; #### Encrypt a image ####
Define password$="Hello Password"
EncryptImageSimple_BF(image_ID, password$)
Define image_gadget_ID=ImageGadget(#PB_Any, 20, 20, 0, 0, ImageID(image_ID))

; #### Decrypt a image ####
Define password$="Hello Password"
DecryptImageSimple_BF(image_ID, password$)
Define image_gadget_1_ID=ImageGadget(#PB_Any, 340, 20, 0, 0, ImageID(image_ID))

Repeat : Until WaitWindowEvent()=#PB_Event_CloseWindow

Here is a code example that shows how to make worthless the images.
You can still see the images but they are worthless for others.

Diffusor

Code: Select all

EnableExplicit

; Hidde your images and textures - Simple 'on place' image crypter

Procedure EncryptImageSimple_BF(image_ID, seed=0)
  Protected i : RandomSeed(seed) ; By Saki
  If Not IsImage(image_ID) Or Not StartDrawing(ImageOutput(image_ID)) : ProcedureReturn 0 : EndIf
  Protected image_length=DrawingBufferPitch()*ImageHeight(image_ID)-1
  Protected *buffer=DrawingBuffer() : StopDrawing()
  For i=0 To image_length : If Random(2)>1 : PokeA(*buffer+i, PeekA(*buffer+i)+Random(255)) : EndIf : Next : ProcedureReturn 1
EndProcedure

Procedure DecryptImageSimple_BF(image_ID, seed=0)
  Protected i : RandomSeed(seed) ; By Saki
  If Not IsImage(image_ID) Or Not StartDrawing(ImageOutput(image_ID)) : ProcedureReturn 0 : EndIf
  Protected image_length=DrawingBufferPitch()*ImageHeight(image_ID)-1
  Protected *buffer=DrawingBuffer() : StopDrawing()
  For i=0 To image_length : If Random(2)>1 : PokeA(*buffer+i, PeekA(*buffer+i)-Random(255)) : EndIf : Next : ProcedureReturn 1
EndProcedure

; ######## Get the result ########

UsePNGImageDecoder() : UseJPEGImageDecoder() : UseTIFFImageDecoder()

Define path$=OpenFileRequester("Select a image", "", "", 0) : If path$="" : End : EndIf

Define image_ID=LoadImage(#PB_Any, path$)

ResizeImage(image_ID, 300, 300)

Define window_ID=OpenWindow(#PB_Any, 0, 0, 660, 340, "Left=encrypted  - Right=decrypted", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)

; #### Encrypt a image ####
Define seed_as_password=1000
EncryptImageSimple_BF(image_ID, seed_as_password)
Define image_gadget_ID=ImageGadget(#PB_Any, 20, 20, 0, 0, ImageID(image_ID))

; #### Decrypt a image ####
Define seed_as_password=1000
DecryptImageSimple_BF(image_ID, seed_as_password)
Define image_gadget_1_ID=ImageGadget(#PB_Any, 340, 20, 0, 0, ImageID(image_ID))

Repeat : Until WaitWindowEvent()=#PB_Event_CloseWindow

Diffusor with AES

Code: Select all

EnableExplicit

; Hidde your images and textures - Simple 'on place' AES based image crypter

Procedure EncryptImageSimple_BF(image_ID, password$="")
  Protected i, ii, i1, depth : UseMD5Fingerprint() ; By Saki
  Protected fixed$=StringFingerprint(password$+"%$(s4DäÖÄö", #PB_Cipher_MD5) : Dim register.q(1)
  Repeat ; 16 Bytes
    PokeA(@register(0)+i, Val("$"+PeekS(@fixed$+ii, 2))) : ii+SizeOf(character)<<1 : i+1 ; Create a key
  Until ii=StringByteLength(fixed$) : i=0 : ii=0
  If Not IsImage(image_ID) Or Not StartDrawing(ImageOutput(image_ID)) : ProcedureReturn 0 : EndIf
  Protected image_length=DrawingBufferPitch()*ImageHeight(image_ID)-1
  Protected *buffer=DrawingBuffer() : StopDrawing()
  RandomSeed(1)
  For i=0 To image_length
    Repeat
      If Not i1 : AESEncoder(@register(0), @register(0), 16, @register(0), 128, 0, #PB_Cipher_ECB) : EndIf
      depth=PeekA(@register(0)+i1) : i1+1 : If i1>15 : i1=0 : EndIf
    Until depth 
    If Random(2)>1
      PokeA(*buffer+i, PeekA(*buffer+i)+depth)
    EndIf
  Next
  ProcedureReturn 1
EndProcedure

Procedure DecryptImageSimple_BF(image_ID, password$="")
  Protected i, ii, i1, depth : UseMD5Fingerprint() ; By Saki
  Protected fixed$=StringFingerprint(password$+"%$(s4DäÖÄö", #PB_Cipher_MD5) : Dim register.q(1)
  Repeat ; 16 Bytes
    PokeA(@register(0)+i, Val("$"+PeekS(@fixed$+ii, 2))) : ii+SizeOf(character)<<1 : i+1 ; Create a key
  Until ii=StringByteLength(fixed$) : i=0 : ii=0
  If Not IsImage(image_ID) Or Not StartDrawing(ImageOutput(image_ID)) : ProcedureReturn 0 : EndIf
  Protected image_length=DrawingBufferPitch()*ImageHeight(image_ID)-1
  Protected *buffer=DrawingBuffer() : StopDrawing()
  RandomSeed(1)
  For i=0 To image_length
    Repeat
      If Not i1 : AESEncoder(@register(0), @register(0), 16, @register(0), 128, 0, #PB_Cipher_ECB) : EndIf
      depth=PeekA(@register(0)+i1) : i1+1 : If i1>15 : i1=0 : EndIf
    Until depth 
    If Random(2)>1
      PokeA(*buffer+i, PeekA(*buffer+i)-depth)
    EndIf
  Next
  ProcedureReturn 1
EndProcedure

; ######## Get the result ########

UsePNGImageDecoder() : UseJPEGImageDecoder() : UseTIFFImageDecoder()

Define path$=OpenFileRequester("Select a image", "", "", 0) : If path$="" : End : EndIf

Define image_ID=LoadImage(#PB_Any, path$)

ResizeImage(image_ID, 300, 300)

Define window_ID=OpenWindow(#PB_Any, 0, 0, 660, 340, "Left=encrypted  - Right=decrypted", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)

; #### Encrypt a image ####
Define password$="Hello Password"
EncryptImageSimple_BF(image_ID, password$)
Define image_gadget_ID=ImageGadget(#PB_Any, 20, 20, 0, 0, ImageID(image_ID))

; #### Decrypt a image ####
Define password$="Hello Password"
DecryptImageSimple_BF(image_ID, password$)
Define image_gadget_1_ID=ImageGadget(#PB_Any, 340, 20, 0, 0, ImageID(image_ID))

Repeat : Until WaitWindowEvent()=#PB_Event_CloseWindow
Last edited by Saki on Mon Jun 28, 2021 9:58 pm, edited 10 times in total.
地球上の平和
User avatar
Keya
Addict
Addict
Posts: 1891
Joined: Thu Jun 04, 2015 7:10 am

Re: Image and Texture crypter - simplest use + AES

Post by Keya »

Random() should not be used for security applications, see CryptRandom()
User avatar
Saki
Addict
Addict
Posts: 830
Joined: Sun Apr 05, 2020 11:28 am
Location: Pandora

Re: Image and Texture crypter - simplest use + AES

Post by Saki »

Keya wrote: Sat Jun 26, 2021 9:22 pm Random() should not be used for security applications, see CryptRandom()
Hi @Keya
These crypters are based on deterministic random generators.
CryptRandom() is not a deterministic random generator, this works not. :wink:
地球上の平和
User avatar
Keya
Addict
Addict
Posts: 1891
Joined: Thu Jun 04, 2015 7:10 am

Re: Image and Texture crypter - simplest use + AES

Post by Keya »

Saki wrote: Sat Jun 26, 2021 9:44 pm Hi @Keya
These crypters are based on deterministic random generators.
CryptRandom() is not a deterministic random generator, this works not. :wink:
Exactly my point.
User avatar
Saki
Addict
Addict
Posts: 830
Joined: Sun Apr 05, 2020 11:28 am
Location: Pandora

Re: Image and Texture crypter - simplest use + AES

Post by Saki »

Keya wrote: Sat Jun 26, 2021 9:48 pm
Saki wrote: Sat Jun 26, 2021 9:44 pm Hi @Keya
These crypters are based on deterministic random generators.
CryptRandom() is not a deterministic random generator, this works not. :wink:
Exactly my point.
And further, how are you going to break a deterministic AES based random generator ?

Best Regards Saki
地球上の平和
User avatar
Keya
Addict
Addict
Posts: 1891
Joined: Thu Jun 04, 2015 7:10 am

Re: Image and Texture crypter - simplest use + AES

Post by Keya »

I was referring to your first example, not the AES example
User avatar
Saki
Addict
Addict
Posts: 830
Joined: Sun Apr 05, 2020 11:28 am
Location: Pandora

Re: Image and Texture crypter - simplest use + AES

Post by Saki »

Caesar encryption is also an encryption.

It is usually sufficient to hide the images, as it is also written in the code above.
Nevertheless, it is not at all easy to override this.
And I would probably use the variant without AES, because it doesn't make any difference if you don't
add the password separately, which is often not possible or too much effort.
地球上の平和
User avatar
Keya
Addict
Addict
Posts: 1891
Joined: Thu Jun 04, 2015 7:10 am

Re: Image and Texture crypter - simplest use + AES

Post by Keya »

Saki wrote: Sat Jun 26, 2021 10:07 pm Caesar encryption is also an encryption.
It is usually sufficient to hide the images, as it is also written in the code above.
Nevertheless, it is not at all easy to override this.
With all due respect, it's trivial to override/break it.
User avatar
Saki
Addict
Addict
Posts: 830
Joined: Sun Apr 05, 2020 11:28 am
Location: Pandora

Re: Image and Texture crypter - simplest use + AES

Post by Saki »

But only if you know exactly what you have in front of you.
You must also know the seed and that it does not work with XOr.
That's a lot of details.
It requires very profound knowledge to start there and rebuild everything.
I don't think it's worth it for a few images.
地球上の平和
User avatar
Keya
Addict
Addict
Posts: 1891
Joined: Thu Jun 04, 2015 7:10 am

Re: Image and Texture crypter - simplest use + AES

Post by Keya »

Saki, at the end of the day it's just a maximum of 32 bits of security (so in reality about 16 bits of security).
You can say all you want about how difficult YOU might find it to break ("It requires very profound knowledge" -- it really DOESN'T), but it's trivial for both cryptanalysts as well as software reverse engineers.

As programmers it is our duty to provide our customers with the BEST - the latest, most secure cryptography. The Caesar cipher is not that, and programmers that promote such amateur ciphers can cast a negative shadow on programmers who are trying to do the right thing.
Last edited by Keya on Sat Jun 26, 2021 10:27 pm, edited 1 time in total.
User avatar
Saki
Addict
Addict
Posts: 830
Joined: Sun Apr 05, 2020 11:28 am
Location: Pandora

Re: Image and Texture crypter - simplest use + AES

Post by Saki »

32 bit is wrong, its only on x86.

As I said, as long as you have to keep a password in the code, it doesn't matter if you use the variant with or without AES.

9 out of 10 users here will probably be satisfied with the variant without AES.
Last edited by Saki on Sat Jun 26, 2021 10:29 pm, edited 1 time in total.
地球上の平和
User avatar
Keya
Addict
Addict
Posts: 1891
Joined: Thu Jun 04, 2015 7:10 am

Re: Image and Texture crypter - simplest use + AES

Post by Keya »

Saki wrote: Sat Jun 26, 2021 10:25 pm32 bit is wrong.
That's what you seed Random() with - a function you acknowledge is deterministic.
Saki wrote: Sat Jun 26, 2021 10:25 pm9 out of 10 users here will probably be satisfied with the variant without AES.
On the contrary, I think 9 out of 10 users here are smart enough to know that Caesar Cipher is not a secure cipher.
Last edited by Keya on Sat Jun 26, 2021 10:33 pm, edited 1 time in total.
User avatar
Saki
Addict
Addict
Posts: 830
Joined: Sun Apr 05, 2020 11:28 am
Location: Pandora

Re: Image and Texture crypter - simplest use + AES

Post by Saki »

It is not a Caesar cypher. :wink:
地球上の平和
User avatar
Keya
Addict
Addict
Posts: 1891
Joined: Thu Jun 04, 2015 7:10 am

Re: Image and Texture crypter - simplest use + AES

Post by Keya »

Saki wrote: Sat Jun 26, 2021 10:31 pm It is not a Caesar cypher. :wink:
Saki wrote:Caesar encryption is also an encryption.
It is usually sufficient to hide the images, as it is also written in the code above.
User avatar
Saki
Addict
Addict
Posts: 830
Joined: Sun Apr 05, 2020 11:28 am
Location: Pandora

Re: Image and Texture crypter - simplest use + AES

Post by Saki »

Yes and, "Caesar cyper" is also an encryption !
But what has that to do with the code, nothing !
This is also really not difficult to recognize.
地球上の平和
Post Reply