.+:::::::::::::::::::::::::::::::::::::::::/ .//`+++++++++++++++++++++++++++++++++++++// s -+/.h+..................................-os s -+/.h/ ss s -+/.h/ ss s -+/.h/ ss s -+/.h/ ss s -+/.h/ ss s -+/.h/ ss s -+/.h/ ss s -+/.h/ ss s -+/.h/ ss s -+/.h/ ss s -+/.h/ ss s -+/.h+ ss s -++-yo////////////////////////////////////y`s -+o-:--------------------------::::-:://:---s -+/ :-.: +:oo- s -+/```````````````````````````````````:-````s ./o//////////+o:::::::::::::::::s+/////////:: ``://////////+s:::::::::::::::::y+/////////:. s .::::/osso::::. .+ `.y +yyyyhNNNmyyyy+ .+ `:h:::::/+:::::::::::::+:///////////////////+-------------------- .o s s::::::::::::s.+ - + -/y .o s ::::::::::::oss+::.+ `-y .o y `+//: .+ `.+/y/::/+:::::::::::::+:::::::::::::::::++:. `////////////////////////////////////:/.
As with each of the articles, it's worth reading them in full, but this time there's a special offer waiting at the end!
Theoretical cryptography and Renaissance art history.
Two of the most exciting topics ever known to mankind.
And as if that were not enough, these two are now finally combined here in this article.
This work attempts to show how concepts of IT security can be used to make art.
The approach has already been briefly mentioned here,
but in the following, the possibilities of crypto art will be explained again in detail.
For this, we will mainly use the technique of manipulating images at the byte level and then using the properties of the BMP file format to create a new image.
First, a few words about art history. My favorite epoch is the Renaissance.
Therefore, I would like to briefly summarize this era here.
Before the Renaissance in Europe there was mainly the so-called icon painting. It was very symbolically charged.
The figures were flat and did not correspond to the real perception. Their size and position in the picture was usually related to social status.
Giotto di Bondone made a break by suggesting a first form of perspective in his frescoes. He also placed Christ on a level with the other figures.
In this way he became the forerunner of the radical change that was now in the offing and that was to characterize the Renaissance.
A little later, Massaccio invented central perspective. This was something completely new at the time. For the first time, painters were able to calculate perspective mathematically. The basis for this was a new, scientific way of looking at the world. His fresco must have had an incredible effect on the viewers, because the central perspective spread in no time.
The new way of looking at the world and at art also spread to Northern Europe. Van Eyck's sense of realistic painting, perfected to a high degree of detail, is visible in the example of the Famous Mirror, in which the entire scene is reflected.
The play with perspective and the characters, as well as their facial expressions, was pushed further and further. Botticelli combines in his Annunciation diverse motives in one. Both a reference back to one of the most common scenes of the time, as well as an extreme architectural perspective and a kind of landscape painting, up to almost exaggerated details in faces and robes.
This is topped only by Mantegna, whose lamentation over the Dead Christ, distorted in an extreme perspective, leaves the viewer at the foot of the bed. This was not only a new form of exhaustion of perspective possibilities, but also a previously quite outrageous representation of Christ himself.
And then... Then comes Michelangelo, the greatest troll in the history of art of all time. He simply gives a f*ck about everything and paints in the Vatican, the holiest place in the world for christians of this time, nothing but naked men's butts...
So far, this has nothing to do with crypto at all, but that's about to change because we will now encrypt the digital representations of Renaissance artworks.
Encryption ensures the confidentiality of data.
This is usually done by encrypting a file with a password.
Of course, a password that is easy to guess does not provide reliable protection.
But cryptographic algorithms can also have weaknesses on their own.
And that can lead to interesting artistic possibilities.
The following is a very basic introduction to some concepts of cryptography and an illustration of their weaknesses using an image example.
Hashing itself basically has nothing to do with encryption.
Nevertheless, it comes up frequently in connection with it.
This is due to the characteristics that a hash brings with it.
A hashing function is a mathematical calculation that produces a specific output with a fixed length from any input.
If the input changes even minimally, the output changes completely.
Furthermore, no conclusions about the original input can be drawn from a hash.
However, one and the same input always generates the same hash.
These properties allow to use hashes for different checks.
In the following code we see how a hash is generated from an image file.
md5sum cambrai.jpg
8c05b44e7276e3b10f7231cd318d0990 cambrai.jpg
8c05b44e7276e3b10f7231cd318d0990 is the hash of the file.
If even a single bit is changed, the result is a completely different hash.
This way it can also be ensured that the file has not been manipulated.
It is the real original, which calculates only this particular hash.
However, a single hash does not yet look very interesting.
Therefore, the following script builds a completely new image from the hashes of the bytes of the source file.
The file is divided into blocks of 16 bytes each, these are hashed and then appended to each other again.
The result is similar to an encryption method shown later, but there is no decryption for this, because it is hashed not encrypted.
The original data cannot be recontructed from the hashes.
The only way to recover the file would be to guess each original bytes individually and compare them against the hash.
import sys from itertools import zip_longest import hashlib data = bytearray(open(sys.argv[1], 'rb').read()) head = data[:54] body = data[54:] a = len(body) c = 0 hashed = b"" # print("This may take a while... (because it's probably the most inefficient way doing this shit)") while body: tmp = body[:16] hashed += bytes.fromhex(hashlib.md5(tmp).hexdigest()) body = body[16:] c += 1 # prnt(f"{c} / {a}", end=' \r') open("output.md5.bmp", "wb").write(head + hashed)
First of all, encoding is not encryption, even if it sometimes looks like it.
Encoding is a way of representing characters using another system.
For example, the binary system is another way to represent a number that we usually know in the decimal system.
If you assign a number to a letter, it can thus also be represented in binary.
"hacking.art" is in binary "01101000 01100001 01100011 01101011 01101001 01101110 01100111 00101110 01100001 01110010 01110100".
Even if you can't read it anymore and it looks somehow "encrypted", it is only transferred from one representation system to another.
In the same way, it can be translated back based on these encoding rules.
Encoding does not provide confidentiality as encryption does.
A well-known and often used encoding is base64.
It is used to transfer data that contains bytes that cannot be represented in ASCII without encoding. It typically looks something like this:
aGFja2luZy5hcnQgaXMgdGhlIGJlc3Qgd2Vic2l0ZSBhYm91dCBoYWNraW5nIGFuZCBhcnQ=
But let's try it out in practice and create Crypto Art with it. For this we again apply the technique already mentioned and modify the bytes of a bmp file, restore the header and look at the result.
import sys import base64 data = bytearray(open(sys.argv[1], 'rb').read()) head = data[:54] body = data[54:] encoded = base64.b64encode(body) open("output.b64.bmp", 'wb').write(head + encoded)
Ok, let's finally get to the first more or less real encryption.
The principle is quite simple. It is a simple symmetric encryption method.
As one of the simplest and least secure methods, it is mainly used today to illustrate basic principles of cryptology.
During encryption, each letter of the plaintext is mapped to a ciphertext letter.
hacking.art
unpxvat.neg
For decryption, the alphabet is rotated to the left by the same number of characters.
Like all monoalphabetic encryption methods, the shift cipher does not provide sufficient security against unauthorized decipherment and can be "cracked" very easily.
The unequal distribution of letters in natural language is not hidden by this type of encryption, so that a frequency analysis reveals the action of a simple monoalphabetic substitution.
In the following script 130 is added to each byte, because only 13 had no visible effect.
If the value is greater than 255, the rest starts again at 0.
Thus each byte is "shifted" by the value.
The overall structure of the image is still visible because of the "bad" encryption.
import sys data = bytearray(open(sys.argv[1], 'rb').read()) head = data[:54] body = data[54:] rot = [] for i in body: if(i+130 < 255): rot.append(i+130) else: rot.append((i+130)-255) open("output.r13.bmp", 'wb').write(head + bytearray(rot))
Exclusive or / exclusive disjunction is a logical operation that is true if and only if its arguments differ (one is true, the other is false).
This is also sometimes used for cryptography.
The encryption goes through the image byte by byte and applies the XOR method. The result is modified bytes, which at first glance looks like encryption.
It works like this:
But as can be seen in the following image, the structures are also clearly visible. In addition, XOR is very easy to decode again. You only need the ciphertext and the plaintext. If you apply XOR to these two again, you get the key.
import sys def str_xor(data, key): for i in range(len(data)): data[i] ^= key[i % len(key)] return data data = bytearray(open(sys.argv[1], 'rb').read()) key = b"ART" # or other key/password head = data[:54] body = data[54:] encoded = str_xor(body, key) open("output.xor.bmp", "wb").write(head + encoded)
Now things are moving more in the direction of encryption.
The Advanced Encryption Standard (AES) is basically considered a secure encryption algorithm.
However, there are different modes in which it can be operated.
The simplest and most insecure mode is called: Electronic codebook (ECB).
Here, the plaintext is divided into equal-sized blocks, each of which is encrypted with the key.
Even if the AES algorithm is good, this particular mode has weaknesses.
This is because patterns can be detected when there are several blocks in the plaintext that are the same.
The same blocks are encrypted exact the same, which allows conclusions to be drawn about the plaintext.
Let's see how it looks like.
import sys from Crypto.Cipher import AES BS = 16 pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS).encode() class AESCipher: def __init__( self, key ): self.key = key def encrypt( self, raw ): raw = pad(raw) cipher = AES.new( self.key, AES.MODE_ECB) return cipher.encrypt( raw ) nerv = AESCipher("Holy Trinity1234") data = bytearray(open(sys.argv[1], 'rb').read()) head = data[:54] body = data[54:] crypt = nerv.encrypt(bytes(body)) open("output.ecb.bmp", 'wb').write(head + crypt)
To remedy the weakness of the ECB mode, the cipher block chaining (CBC) mode was developed. In this mode, the individual encrypted blocks are chained together in such a way that patterns are no longer recognizable. For this purpose, a so-called initialization vector is used at the beginning and each following block is linked to the previous one by an XOR operation.
Also from the image you can see that it has created a complete encryption. This is how it should look when it is secure.
But encryption alone is not enough to protect data from being manipulated.
It is interesting to note that even encrypted data can be modified, despite encryption.
This means that when the data is decrypted, the result is different from the original plaintext.
A classic attack that exploits this is the so-called bit flipping attack.
An encrypted message is manipulated in such a way that other data arrives at the recipient than intended.
For example, if the right bytes are swapped in the right block, the original "login=false" can become "login=true" after decryption.
This is not so easy to show with images, but nevertheless we can observe the effect when bytes are exchanged in the encrypted image.
Each glitch in the image is a byte, which was decrypted "wrongly".
import sys import base64 from Crypto.Cipher import AES from Crypto import Random BS = 16 pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS).encode() unpad = lambda s : s[:-ord(s[len(s)-1:])] class AESCipher: def __init__( self, key ): self.key = key def encrypt( self, raw ): raw = pad(raw) iv = Random.new().read( AES.block_size ) cipher = AES.new( self.key, AES.MODE_CBC, iv ) return iv + cipher.encrypt( raw ) def decrypt( self, enc ): iv = enc[:16] cipher = AES.new(self.key, AES.MODE_CBC, iv ) return unpad(cipher.decrypt( enc[16:] )) nerv = AESCipher("andrea mantegna!") data = bytearray(open(sys.argv[1], 'rb').read()) head = data[:54] body = data[54:] if(sys.argv[2] == "enc"): crypt = nerv.encrypt(bytes(body)) open("aescbc.enc.bmp", 'wb').write(head + crypt) elif(sys.argv[2] == "dec"): crypt = nerv.decrypt(bytes(body)) open("output.cbc.bmp", 'wb').write(head + crypt) ################# BASH ########################### # python3 aescbc.py ~/cryptoart/mantegna.bmp enc # sed -i 's/\xAC/\xAB/g' aescbc.enc.bmp # python3 aescbc.py aescbc.enc.bmp dec
Now, finally my favorite encryption method developed by the awesome Ange Albertini: Angecryption.
Ange Albertini has managed to transform an image by encrypting it into another image.
And to return to Michelangelo going crazy in Vatican mentioned at the beginning, we will turn an image of one of his butt paintings into an image of a super tiny dick USING CRYPTO!!!11
wget https://raw.githubusercontent.com/angea/corkami/master/src/angecryption/angecrypt.py python angecrypt.py butt.png dick.png lol.png "ange albertini12" aes cat > decrypt.py <<EOF from Crypto.Cipher import AES algo = AES.new('ange albertini12', AES.MODE_CBC, '\x93ted\xfb\xe6\xd4l4d\r?\xcd`\xab\xdf') with open('lol.png', "rb") as f: d = f.read() d = algo.encrypt(d) with open('output.lol.png', "wb") as f: f.write(d) EOF python decrypt.py
To all you art collectors: There is now a once-in-a-lifetime chance to buy an original Crypto-Artwork and support my work.
You will get one unique, original and signed image of an artwork from hacking.art, encrypted with a password of your choice.
And now the best part!
It will be stored and displayed with your owner information encrypted in the
Encrypted Gallery
When sold, a hash is generated from the name of the buyer, the price and date of sale, as well as the resulting Crypto-Artwork. Following this structure.
{ "owner": "", "date": "", "price": "", "name_artwork": "", "hash_artwork": "" }
These infos will be published here on this website, with a screenshot of the sold image, the hash and the corresponding publickeys.
To verify the authenticity, the hash is additionally signed with the sellers privatekey.
This way everyone can verify the correct owner of a Crypto-Artwork.
The original image is securely encrypted again and sent exclusively to the new owner!
The particular feature is: the artwork is not just a boring gif with some metadata in a blockchain, but
The artwork itself is encrypted and additionally cryptographically signed.
This way the art is bulletproof millitary grade double encrypted!
This will make them encrypted Crypto-Art!
Or better call it Crypto-Crypto-Art.
100% Secure, Unhackable, Encrypted and Crypto-Signed Crypto-Crypto-Art!!!
If you buy one you will also support my next project: turning the NFT market into a forkbomb!
For more Information visit the Encrypted Gallery.
Below are the hashes and signatures of the of the original pieces from this article.