At their core, blockchain technologies rely on cryptography and encryption algorithms. While I am not a developer, I do have curiosity in understanding how blockchains work. Hive has always been a great playground to understand these concepts and see the practical implementations. Recently, I started dedicating time in understanding how encryptions work. In their simplest form there are two kinds of encryption methods: symmetric and asymmetric.
Symmetric encryption requires encrypting a message or a file using a secret phrase. Then to share this encrypted message or file with someone else, we also need to share the secret phrase. The recipient of the encrypted message or file can use the secret phrase to decrypt the message or file. There are many risks involved in sharing secret keys or phrases. Someone that wasn't suppose to or intended to have access may gain access to them and compromise this communication method. But also this may create secret key/phrase management issues, as every single message and file will need a new secret key or phrase.
Another method of encrypting is called Asymmetric Encryption. This method requires public/private key pairs, just like we see keys on Hive. On Hive every account has a public and a private keys. For example each posting private key has its public posting key as well. For encrypting and decrypting messages purposes we will use memo private and public keys.
They way asymmetric encryption works, is when I need to send an encrypted message to someone, all I need is my private memo key and recipient's public memo key. Then, the recipient will be able to decrypt the encrypted message using their private memo key. This way there is no need to share any secret keys or phrases with anybody. Everybody keep their private keys secure and only available to themselves. The public keys sort of work as destination of the message, or a mail box address, or intended recipient. Public keys, as the name suggest are public and anybody can see them.
This public/private keys combination and ability to transact peer-to-peer makes the blockchain magic happen. As long as blockchain is decentralized and there are no risks of core code protocols being tampered with, communicating in peer-to-peer encrypted manner becomes super secure. In fact, we don't even need to use Hive or any other blockchain for asymmetric encryption and decryption. There are libraries available that generated private/public key pairs for this purpose. I main use python, but I am sure other programming languages have similar libraries. But I am more interest in Hive and how we can achieve this using Hive blockchain and keys.
Many of you already might be familiar with encrypted memo messages in Hive wallet. We are able to send encrypted messages and sign them with memo private keys when making transfers in the wallet. For this, we need to start the message with a hashtag. That is not what I am trying to do here. What I want to do is to encrypt a message without storing any of the data on the Hive blockchain, then let the recipient decrypt it. So, let's look at how we can do this using Beem, Hive's python library. I believe, Holger is no longer maintaining or updating Beem. While it works for the most part, there might be things you may not be able to do.
First lets take a look how we can encrypt a message using Beem:
from beem import Hive
from beem.nodelist import NodeList
from beem.memo import Memo
import getpass
def get_hive_nodes():
nodelist = NodeList()
nodelist.update_nodes()
nodes = nodelist.get_hive_nodes()
return nodes
def encrypt_message(sender, sender_memo_wif, receiver, nodes, message):
hive = Hive(node=nodes, keys=[sender_memo_wif])
memo = Memo(from_account=sender,to_account=receiver, blockchain_instance=hive)
encrypted_message = memo.encrypt(message)
return encrypted_message
def main():
nodes = get_hive_nodes()
sender = 'geekgirl'
sender_memo_wif = getpass.getpass(prompt="Enter your Hive memo key:")
receiver = 'librarian'
message = 'Hive is the most decentralized blockchain!'
encrypted_message = encrypt_message(sender, sender_memo_wif, receiver, nodes, message)
print(encrypted_message)
if __name__ == "__main__":
main()
There is a main function and couple helper functions. If you look at the main function, first we get nodes which will allow us create an instance of Hive. Then we need account names for the sender and receiver of the message. We also need a private memo key of the sender. We get is using a prompt, for security purposes. Once we have the message, we pass all of this data to our helper encrypt function. This function creates a Hive instance using the private memo key. (I will explain why in a minute). Then we create a memo instance using sender name, receiver name, and the blockchain instance. Afterwards we simply using encrypt() method to encrypt the message. Finally, the result is returned to the main function.
The result of this encryption will in a dictionary format that will have three key/pair values: message, sender's public key, receiver's public key. Now we are ready to share this encrypted message dictionary with the recipient, who can use decryption script to find out what the message is. Ok. So, the reason I had to create a Hive instance with private memo key is that .unlock_wallet("secret") method of Memo class didn't work. I have no idea why. If you know please let me know. If that did work, I would prefer not to use private keys in Hive instance and instead unlock the wallet with memo class instance.
Now, we are ready to decrypt the message.
from beem import Hive
from beem.nodelist import NodeList
from beem.memo import Memo
import getpass
def get_hive_nodes():
nodelist = NodeList()
nodelist.update_nodes()
nodes = nodelist.get_hive_nodes()
return nodes
def decrypt_message(nodes, encrypted_message, receiver_memo_wif):
hive = Hive(node=nodes, keys=[receiver_memo_wif])
memo = Memo(blockchain_instance=hive)
decrypted_message = memo.decrypt(encrypted_message['message'])
return decrypted_message
def main():
nodes = get_hive_nodes()
receiver_memo_wif = getpass.getpass(prompt="Enter your Hive memo key:")
encrypted_message = {'message': '#55sS1vFysyMbpPKeGcdNz2imc2nXcfn1YwzYgE6jTr37zeT2Bj6ThCkTmzoZmiT8eApbAtEiczVAKNxce71EByVreyJ2otpU4x1eoCEmXn33iCsv9CrQmPvw8Sh6Qk43SVUYckgzkX1xFE8DeErv6PCJFMuiHVzaZYGNyoHpuf1zi', 'from': 'STM6uRCE7yv1XhPuV3mrtQf5mE1oDxF3P3ehqX3dcizDdVb8HooYJ', 'to': 'STM5fWMqNY8J8EStWHM4ogk6cZcW3e5zP9tPzxasA6tMXL91mZCrt'}
decrypted_message = decrypt_message(nodes, encrypted_message, receiver_memo_wif)
print(decrypted_message)
print(len(decrypted_message))
if __name__ == "__main__":
main()
The code is very similar to the encryption script. This time, however, we do not need to include sender and receiver names. Only receiver's private memo key is enough to decrypt the message. You may include sender and receiver if you like. Originally, that's what I did. Then I found out they are not needed. Of course this is just the basics of encrypting and decrypting messages using Hive memo keys. But I find it to be powerful enough to get started with any ideas you may have to implement these methods in your new cool apps or use cases.
A couple of things to note. When you encrypt the message, a hashtag is automatically added as the first character of the encrypted message. When this message is decrypted, the hashtag remains. You will have to remove the hashtag after decrypting the message, as hashtag wasn't part of the original message.
I tried to keep this as simple as possible to help anybody who is new to coding or encryption methods. If you have any questions feel free to ask in the comments. I am no expert, just trying to learn and understand things. I can see benefits of using encryption in creating new cool apps. I am a fond of privacy, and encryption makes privacy possible. While the examples above only show peer-to-peer communication, it will also be possible to send encrypted message to a group of people. The way you can achieve that is: one send everybody encrypted messages separately, or send encrypted message to a dedicated account that everybody in the group has access to.
Another thing I will need to experiment with is, how changing/updating keys will affect already encrypted/decrypted messages. For example if you gave access to a group of people an access to my content, then changed my mind and wanted to revoke the access, would I be able to achieve this by simply changing my keys? Changing keys is super easy on Hive. Maybe we can talk about this next time.
Huge thanks to @ausbitbank for guiding me to the right direction when I asked him about this topic. When I couldn't figure out how to experiment asymmetric encryption on Hive, Ausbitbank was able to help me with providing a link to Beem documentation page for Memo. That is what I used when writing the codes above. Feel free to read the documentation yourself and correct my mistakes.
Lastly, according to the Beem documentation it is also possible to encrypt and decrypt binary files. I did not get a chance to experiment with that yet. But that will be the next step for me in learning more about encrypting and decrypting using Hive keys. While, this method doesn't require storing anything on Hive blockchain, it is not that difficult to do so either. I have written in the past how super easy it is to store data as custom_json on Hive. I may need to revise that using encryption in the future.
From my understanding symmetric encryption is more efficient compared to asymmetric encryption. The best way to build tools and apps maybe using the combination of symmetric and asymmetric encryptions. For example large amount of data and files can be stored in centralized databases using symmetric encryption, and only the keys that decrypt the symmetric encryption will be stored on blockchain like Hive using asymmetric encryption. Something to consider in building apps or tools. But for personal use that doesn't require scaling, modern computers should be enough to handle the load with only using asymmetric encryption.
Feel free to share your thoughts, knowledge, and experiences with encryption in general and specific to Hive in the comments.