Image and Texture Crypter - Advanced - AES256/CBC - Also for professional using

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 - Advanced - AES256/CBC - Also for professional using

Post by Saki »

Today I have made an image crypter for you, which fulfills the highest demands and can
also be used in this form in professional applications or games.

This crypter works with AES-256 in CBC mode with a crypt randomized IV.

The special thing about it is that no temporary unencrypted images are created.
Everything is done directly in memory, which provides a very high security.

If you encrypt the same image a million times with this crypter, each of these encrypted images is different down to the bit level.

With this you can solve the problem of encrypted images comprehensively and completely.

All image formats can be encrypted, for example also Gif.

The Crypter is extremely fast.
The images and textures can also be easily read in a batch process and allocated in a flash.

Have fun with it


Encrypter

Code: Select all

EnableExplicit

Procedure LoadImage_Encrypt_and_Save_BF(source_path_image$, destination_path_image$, password$, crypt_extender$=" [encrypted]")
  UseSHA3Fingerprint() ; By Saki - Advanced AES CBC mode image Encrypter with crypt randomized IV
  Protected fixed$=StringFingerprint(password$+"%$(s4DäÖÄö", #PB_Cipher_SHA3), i, ii, *buffer : Dim register.q(5)
  Protected extension$="."+GetExtensionPart(source_path_image$)
  destination_path_image$=GetPathPart(source_path_image$)+GetFilePart(source_path_image$)
  destination_path_image$=RemoveString(destination_path_image$, extension$) : destination_path_image$+crypt_extender$+extension$
  Repeat ; 32 Bytes
    PokeA(@register(0)+i, Val("$"+PeekS(@fixed$+ii, 2))) : ii+SizeOf(character)<<1 : i+1 ; Create a key
  Until ii=StringByteLength(fixed$)
  Protected file=ReadFile(#PB_Any, source_path_image$) : If Not file : ProcedureReturn -21 : EndIf
  If OpenCryptRandom() : CryptRandomData(@register.q(4), 16) : Else : RandomData(@register.q(4), 16) : EndIf
  Protected length=Lof(file) : *buffer=AllocateMemory(length+16) : If Not *buffer : CloseFile(file) : ProcedureReturn -9 : EndIf
  If Not ReadData(file, *buffer, length) : FreeMemory(*buffer) : CloseFile(file) : ProcedureReturn -21 : EndIf
  CloseFile(file)
  Protected *buffer_1=AllocateMemory(length+16) : If Not *buffer_1 : FreeMemory(*buffer) : ProcedureReturn -9 : EndIf
  CopyMemory(@register(4), *buffer_1+length, 16)
  If Not AESEncoder(*buffer, *buffer_1, length, @register(0), 256, @register(4), #PB_Cipher_CBC)
    FreeMemory(*buffer) : FreeMemory(*buffer_1) : ProcedureReturn -9
  EndIf
  FreeMemory(*buffer) : file=CreateFile(#PB_Any, destination_path_image$)
  If Not file : FreeMemory(*buffer_1) : ProcedureReturn -22 : EndIf
  If WriteData(file, *buffer_1, length+16)<>length+16 : FreeMemory(*buffer_1) : CloseFile(file) : ProcedureReturn -22 : EndIf
  CloseFile(file)
  FreeMemory(*buffer_1)
  ProcedureReturn 1
EndProcedure

; #### Encrypt a image ####

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

Define destination_path_image$=source_path_image$

Define password$="Hello Password"
LoadImage_Encrypt_and_Save_BF(source_path_image$, destination_path_image$, password$)


Decrypter

Code: Select all

EnableExplicit

Procedure LoadImage_and_Decrypt_BF(source_path_image$, password$, recreate_file=0, crypt_extender$=" [encrypted]")
  UseSHA3Fingerprint() ; By Saki - Advanced AES CBC mode image Decrypter with crypt randomized IV
  Protected fixed$=StringFingerprint(password$+"%$(s4DäÖÄö", #PB_Cipher_SHA3), i, ii : Dim register.q(5)
  Repeat ; 32 Bytes
    PokeA(@register(0)+i, Val("$"+PeekS(@fixed$+ii, 2))) : ii+SizeOf(character)<<1 : i+1 ; Create a key
  Until ii=StringByteLength(fixed$)
  Protected file=ReadFile(#PB_Any, source_path_image$)
  If Not file : ProcedureReturn -21 : EndIf : Protected length=Lof(file), *buffer=AllocateMemory(length)
  If Not *buffer : CloseFile(file) : ProcedureReturn -9 : EndIf : length-16 : FileSeek(file, length)
  If ReadData(file, @register.q(4), 16)<>16 : CloseFile(file) : ProcedureReturn -21 : EndIf : FileSeek(file, 0)
  If ReadData(file, *buffer, length)<>length : FreeMemory(*buffer) : CloseFile(file) : ProcedureReturn -21 : EndIf
  CloseFile(file)
  Protected *buffer_1=AllocateMemory(length) : If Not *buffer_1 : FreeMemory(*buffer) : ProcedureReturn -9 : EndIf
  If Not AESDecoder(*buffer, *buffer_1, length, @register(0), 256, @register(4), #PB_Cipher_CBC)
    FreeMemory(*buffer) : FreeMemory(*buffer_1) : CloseFile(file) : ProcedureReturn -9
  EndIf
  FreeMemory(*buffer) 
  If recreate_file
    source_path_image$=RemoveString(source_path_image$, crypt_extender$, #PB_String_NoCase)
    file=CreateFile(#PB_Any, source_path_image$)
    If Not file : ProcedureReturn -21 : EndIf
    If WriteData(file, *buffer_1, length)<>length : CloseFile(file) : FreeMemory(*buffer_1) : ProcedureReturn -22 : EndIf
    CloseFile(file) : FreeMemory(*buffer_1)
    ProcedureReturn 1
  Else
    Protected image_ID=CatchImage(#PB_Any, *buffer_1, length) : FreeMemory(*buffer_1)
    If Not image_ID : ProcedureReturn -6 : EndIf : ProcedureReturn image_ID
  EndIf
EndProcedure

; ######## Decrypt a image ########

UsePNGImageDecoder() : UseJPEGImageDecoder() : UseTIFFImageDecoder() : UseGIFImageDecoder()

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

Define recreate_image_file=0 ; Recreate a decrypted image from a encrypted image

Define password$="Hello Password"

Define image_ID=LoadImage_and_Decrypt_BF(source_path_image$, password$, recreate_image_file)

If recreate_image_file : If Not image_ID : MessageRequester("Hint", "Can not create a decrypted image") : EndIf : End : EndIf

Define window_ID=OpenWindow(#PB_Any, 0, 0, 650, 400, "Decrypted Image", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
If IsImage(image_ID)
  If UCase(GetExtensionPart(source_path_image$))<>"GIF" : ResizeImage(image_ID, 300, 300) : EndIf
  Define image_gadget_ID=ImageGadget(#PB_Any,
                                     WindowWidth(window_ID)/2-ImageWidth(image_ID)/2,
                                     WindowHeight(window_ID)/2-ImageHeight(image_ID)/2,
                                     0,
                                     0,
                                     ImageID(image_ID))
Else
  CloseWindow(window_ID)
  MessageRequester("Hint", "Decrypted Image not usable")
  End
EndIf

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

Re: Image and Texture Crypter - Advanced - Also for professional using

Post by Keya »

fixed$=StringFingerprint(password$+"%$(s4DäÖÄö", #PB_Cipher_SHA3)
???
User avatar
Saki
Addict
Addict
Posts: 830
Joined: Sun Apr 05, 2020 11:28 am
Location: Pandora

Re: Image and Texture Crypter - Advanced - Also for professional using

Post by Saki »

Codes updated

This is a static salt.
You can change it as you like.
It can also be used, for example, to patch the exe from the outside to personalize the crypter.
This salt changes the password absolutely, if it is changed.
地球上の平和
User avatar
Keya
Addict
Addict
Posts: 1891
Joined: Thu Jun 04, 2015 7:10 am

Re: Image and Texture Crypter - Advanced - Also for professional using

Post by Keya »

Saki wrote: Mon Jun 28, 2021 8:57 pmThis is a static salt.
Salts by definition are meant to be cryptographically secure random data, not static/hard-coded constants.

The basic idea is that instead of having to guess or brute-force 1 challenge ("What is the password?"), an attacker would have to break 2 challenges ("What is the password, and what is the salt?"), which is exponentially more difficult and defeats precomputed rainbow tables.

There is no 2nd challenge with a static/hard-coded salt, defeating their purpose - it's just a 1-challenge problem again.

A static salt therefore adds very little security (other than getting around non-salted original rainbow tables, but a new set of rainbow tables can easily be made because of the static salt, whereas you can't make rainbow tables for random salts), does nothing to slow down brute-force attacks (the attacker simply appends/prepends your static salt), and it may even compromise the security of some algorithms because you're giving the attacker the knowledge of (in this case) 10 fixed bytes of the password.

See https://en.wikipedia.org/wiki/Salt_(cryptography) (where the word 'static' doesn't exist, but "Salt re-use" is listed under the "Common mistakes" section).
User avatar
Saki
Addict
Addict
Posts: 830
Joined: Sun Apr 05, 2020 11:28 am
Location: Pandora

Re: Image and Texture Crypter - Advanced - Also for professional using

Post by Saki »

After all, it's just a static add-on.
Imagine that 10 000 people use the crypter - LOL
Then you can attack it in principle always with the same password.
If you use the thing for the cloud, then you can change the static salt.
Nobody else knows your static salt, you can also patch it from the outside.
So someone else can't do a brute force attack on your password,
because the static salt is used by you alone, it's your personalization, that's all.
Last edited by Saki on Tue Jun 29, 2021 8:39 am, 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 - Advanced - Also for professional using

Post by Keya »

Saki wrote: Tue Jun 29, 2021 12:52 am After all, it's just a static add-on.
But you're recommending it for professional use, as per the thread title, when it fails very basic cryptographic standards.
Saki wrote: Tue Jun 29, 2021 12:52 am Nobody else knows your static salt
Yes they do - because you hard-coded it. You've given it to the attacker on a platter. And now they know it's not a random salt, it's fixed. Game over - the attacker has now solved the 2nd challenge ("what is the seed?") because you literally gave it to them, so they now only need to solve the 1st challenge - "what is the password?"

Again I refer you to https://en.wikipedia.org/wiki/Salt_(cryptography) where "Salt re-use" (ie. "static salt") is listed under the "Common mistakes" section.
User avatar
Saki
Addict
Addict
Posts: 830
Joined: Sun Apr 05, 2020 11:28 am
Location: Pandora

Re: Image and Texture Crypter - Advanced - Also for professional using

Post by Saki »

I work with software registers at AES.
The static salt does nothing different than the seed at random.
It creates a start state of the crypter defined by me, which I can change with the key.
You set the crypter in such a way, that its start position is unique and probably no human on this earth has a compatible crypter.
You have your own personal Crypter, which no other person has.
Last edited by Saki on Tue Jun 29, 2021 8:36 am, 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 - Advanced - Also for professional using

Post by Keya »

Saki wrote: Tue Jun 29, 2021 1:37 am I work with software registers at AES.
I have no idea what this means or how it's applicable to this discussion, and none of your code works directly with software registers - there is no inline assembly code using registers?
Saki wrote: Tue Jun 29, 2021 1:37 am The static salt does nothing different than the seed at random.
By your own definition then, a static/hard-coded salt/seed is therefore not cryptographically secure. That's why we have CryptRandom() to use instead of just Random() for example. And to be fair, you do use CryptRandom in your code ... but you also use a static seed, which brings the code undone.

When it comes to cryptography, everything has to be PERFECT. Cryptography rarely gets broken -- implementations of cryptography are REGULARLY broken. And it's up to us - programmers - to ensure we're giving our customers the best of the best, and not giving qualified programmers a bad name by poor implementation.
User avatar
Saki
Addict
Addict
Posts: 830
Joined: Sun Apr 05, 2020 11:28 am
Location: Pandora

Re: Image and Texture Crypter - Advanced - Also for professional using

Post by Saki »

This is absolutely wrong and partly also quite nonsense.

The encryption is as secure as your password and nothing else.

If you set a static internal salt your password will neither get stronger nor weaker,
but the key will absolutely not fit into the same lock as before.
You don't have to hide that either, just like you don't have to hide an IV.

Best Regards Saki
地球上の平和
User avatar
Saki
Addict
Addict
Posts: 830
Joined: Sun Apr 05, 2020 11:28 am
Location: Pandora

Re: Image and Texture Crypter - Advanced - Also for professional using

Post by Saki »

Decrypter enhanced.
地球上の平和
User avatar
Keya
Addict
Addict
Posts: 1891
Joined: Thu Jun 04, 2015 7:10 am

Re: Image and Texture Crypter - Advanced - Also for professional using

Post by Keya »

Then you should modify the first sentence at Wikipedia's Salt page: "In cryptography, a salt is random data" (not static, as you argue it is)

You should also modify Salt re-use (static salt) which explains why your "static salt" is a "common mistake".

Please don't let personal pride get in the way of learning. EVERYONE makes mistakes when implementing crypto (I know I have - everyone has!!!), but we should EMBRACE our errors and learn from them, and thank our colleagues for pointing out issues, as our customers DEMAND that we're giving them the best possible.
User avatar
Saki
Addict
Addict
Posts: 830
Joined: Sun Apr 05, 2020 11:28 am
Location: Pandora

Re: Image and Texture Crypter - Advanced - Also for professional using

Post by Saki »

You define an error in my code where there is none, and then lecture me with very strange arguments.

If you want a salt, you must attach it to your password, no one is stopping you ! :wink:
地球上の平和
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5342
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Image and Texture Crypter - Advanced - AES256/CBC - Also for professional using

Post by Kwai chang caine »

I have tested this code too 8)

Like usually i use the same image :wink:

Image

And it work perfect !!!
SHE'S BACK
:mrgreen:

Image

Thanks for sharing 8)
ImageThe happiness is a road...
Not a destination
User avatar
Saki
Addict
Addict
Posts: 830
Joined: Sun Apr 05, 2020 11:28 am
Location: Pandora

Re: Image and Texture Crypter - Advanced - AES256/CBC - Also for professional using

Post by Saki »

Hi Kwai,
thank you very much for testing.

A special feature of this crypter is that you can easily build an image viewer
that displays the encrypted images without having to decrypt them first on your storing media.

No temporary unencrypted files are created.
When the viewer is turned off, everything is gone.

Maybe someone would like to build one.
This is quite simple, as existing viewers can be easily modified.
地球上の平和
User avatar
pdwyer
Addict
Addict
Posts: 2813
Joined: Tue May 08, 2007 1:27 pm
Location: Chiba, Japan

Re: Image and Texture Crypter - Advanced - AES256/CBC - Also for professional using

Post by pdwyer »

It seems to me that in this case, the salt isn't actually a flaw, it's just meaningless.
The only thing it seems to prevent (or at least make more difficult) is that other software packages with using the same algo and key will likely fail to decrypt this until this software is pulled apart and the salt checked and then added to the pwd.

I guess what is a little misleading is that the presence of the salt makes it look like weak passwords are being handled or improved but that's only true in a simple sense and not really a true security sense. 10 people all using the password "password123" will all generate the same key.

I don't think this kind of software is really a good use case for salting. If salt is generated randomly then you won't be able to decrypt (since it's not stored) and if you ask the user to add you might as well just ask the user for a stronger password.

Unless this is going to be used in a back-end password manager or something where the salt is generated for each password and kept, I would just remove the salt and perhaps replace it with a check and warning for poor passwords, encourage either long random strings or longer pass phrases.

Just my 2 yen
Paul Dwyer

“In nature, it’s not the strongest nor the most intelligent who survives. It’s the most adaptable to change” - Charles Darwin
“If you can't explain it to a six-year old you really don't understand it yourself.” - Albert Einstein
Post Reply