You can download an executable here.
I've done a lot of griping about how there's no memo encryption implemented on the frontends I use. Last night I decided to stop griping and write some code about it. I made a laser-focused, no frills whatsoever, desktop application that (hopefully) anyone can use to encrypt transfer memos, or just about whatever text they like.
The source will be included near the end of this post, so if you want to audit it or tell me how it could be improved I'd love to hear from you.
As you can see the form is very minimal. One needs only provide an encryption key in the form of any text, input the cyphertext or cleartext, and click the corresponding button to encrypt or decrypt the message. This is an AES implementation, which means it's symmetric key encryption. In plain English that means that the same key is used for encrypting and decrypting a given message. I will be working on another version that uses a Diffie-Hellman key exchange protocol soon.
I make no claims that the encryption is absolutely secure!
You will still need some way of securely sharing a key with anyone you want to be able to read an encrypted memo. Obviously a secret can't be posted on a public blockchain like Hive, but I know lots of you use other channels like Discord that aren't quite so public to communicate. My next version will address this limitation, allowing users to exchange keys publicly without adversaries being able to decrypt their messages.
While this utility can provide privacy against eavesdropping it, like virtually any cryptosystem, is not completely bulletproof. Even someone with cryptography know-how can't decrypt your messages without the key, but state-level actors and the like could probably break this encryption. AES is actually used in the real world, such as for WiFi security, but I wouldn't stake my life on this application. I'm not liable for any misadventures you might get into using this software. Protect yourself, don't be foolish.
Things to note.
Just to reiterate that last part, I am not an expert in security or cryptography. I'm just a programmer who cares about privacy. Also do not put your Hive private keys into this then send them over a public channel, like the blockchain, expecting them to be safe. While proper management of the encryption key might make this acceptably secure, I don't want you to lose money. Please, take my advice and don't risk it.
With all that out of the way...
I do hope someone at least gives it a try. It ought to be perfectly acceptable for sending private transfer memos, assuming you securely share keys as I mentioned. This is end-to-end encryption, meaning that both you and the recipient(s) of your secret message need this application (or any congruent implementation) to transmit hidden messages.
No need to keep it on Hive.
You could use this utility to encrypt emails or Twitter posts or whatever your heart desires. I'm thinking of using it for SMS myself, since I do my texting from my computer.However you end up using it I hope you enjoy it, and maybe you'll even get some utility out of it. If I can provide one person with even marginally enhanced privacy it's more than worth it in my book. I'd probably break even with just a laugh.
Without further ado, here is the source code.
There are 3 files in the MemoEncryptor package.
I'll start with the class that handles the AES protocol.
AES.java
package MemoEncryptor;
import java.security.MessageDigest;
import java.util.Arrays;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class AES {
private static SecretKeySpec secret;//the secret encryption key
private static byte[] keybytes;//a container for it's bytes
private static void setkey(String keystring){//function to initialize the encryption key given a passphrase string
MessageDigest sha = null;//declare hash object for turning passphrase to key
try{
keybytes = keystring.getBytes();//turn passphrase to bytes
sha = MessageDigest.getInstance("SHA-1");//initialize hash algorithm
keybytes = sha.digest(keybytes);//do hashing
keybytes = Arrays.copyOf(keybytes, 16);//ensure proper length of byte array
secret = new SecretKeySpec(keybytes, "AES");//construct AES encryption key object
}catch (Exception e){
System.out.println("Error setting key: " + e.toString());
}
}
public static String encrypt(String cleartext, String key){//encrypt a given text with a given passphrase
try{
setkey(key);//turn passphrase to AES encryption key
Cipher aes = Cipher.getInstance("AES/ECB/PKCS5Padding");//instantiate AES object
aes.init(Cipher.ENCRYPT_MODE, secret);//initialize AES instance for encryption with the encryption key
return Base64.getEncoder().encodeToString(aes.doFinal(cleartext.getBytes()));//return AES encrypted string
}catch (Exception e){
System.out.println("Error encrypting: " + e.toString());
}
return null;
}
public static String decrypt(String ciphertext, String key){//decrypt a given text with a given passphrase. mostly as above except...
try {
setkey(key);
Cipher aes = Cipher.getInstance("AES/ECB/PKCS5Padding");
aes.init(Cipher.DECRYPT_MODE, secret);//...initialize for decryption...
return new String(aes.doFinal(Base64.getDecoder().decode(ciphertext)));//...and return decrypted string
} catch (Exception e){
System.out.println("Error decrypting: " + e.toString());
}
return null;
}
}
Then there's the class that handles that cute little swing window.
GuiHandler.java
package MemoEncryptor;import javax.swing.;
import java.awt.;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;public class GuiHandler implements ActionListener{
JFrame frame = new JFrame("Symmetric Key Memo Encryptor");
final JTextField keyin = new JTextField("Put the encryption key here. These boxes resize to fit contents.");
final JTextField memoclear = new JTextField("Put memo cleartext here, or it will appear here when decrypting.");
final JTextField memocypher = new JTextField("Put memo cyphertext here, or it will appear here when encrypting");
final JButton encryptbutton = new JButton("Encrypt");
final JButton decryptbutton = new JButton("Decrypt");GuiHandler(){ init(); } public void init(){//place components on swing window, and set starting dimensions frame.setPreferredSize(new Dimension(500,150)); frame.setLayout(new FlowLayout()); frame.getContentPane().add(keyin); frame.getContentPane().add(memoclear); frame.getContentPane().add(memocypher); frame.getContentPane().add(encryptbutton); frame.getContentPane().add(decryptbutton); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); frame.setVisible(true); encryptbutton.addActionListener(this);//make buttons produce actions when clicked decryptbutton.addActionListener(this); } @Override public void actionPerformed(ActionEvent actionEvent) {//if an action is caught String keystring, cipherstring, clearstring; keystring = keyin.getText();//fill internal variables from textfields cipherstring = memocypher.getText(); clearstring = memoclear.getText(); if(actionEvent.getSource().equals(encryptbutton)){//detect which button was pressed and do cooresponding action System.out.println("Encrypt button pressed."); cipherstring = AES.encrypt(clearstring, keystring); } else if(actionEvent.getSource().equals(decryptbutton)){ System.out.println("Decrypt button pressed."); clearstring = AES.decrypt(cipherstring, keystring); } memocypher.setText(cipherstring);//post results to swing window memoclear.setText(clearstring); }}
Not sure why there's a subwindow in that code box, but moving on there's the tiny main class. This is the execution entry point.
Main.java
package MemoEncryptor;public class Main {
public static void main(String[] args) {
GuiHandler window = new GuiHandler();//make a new GUI.
}
}
If you understood any of that, fantastic!
I'd be exstatic to hear any feedback whatsoever. This isn't the seamless integration of a Diffie-Hellman encryption protocol into a hive frontend I'd like to see, but it's a start. I've decided that I'm going to start doing bite sized little projects like this. That way I can actually finish them undaunted by a large ambitious project. I plan to work my way up to making my own frontend, much in the way that I make comments to work myself up to larger root posts.
Conclusion
I wrote this with the help of an autocompleting IDE, as well as with reference to code publically available on the internet. I don't think either of those are any issue, but I wanted to mention that to show that it wasn't done in a vaccuum. I'll give credit were I think it's due; thanks to JetBrains for their IDE, and thanks to the internet at large and stackoverflow. I don't remember the names of the particular authors of code snippets I've looked at to learn this stuff over the years, but deep thanks to anyone out there willing to put code into the public domain. All the documenting comments are written by me, and I take pains to avoid just copying code without trying to understand it or write it in my own style.
Thanks for reading!
Stay safe and private out there, dear reader.