Basically I found this code, posted by someone, which allows you to encrypt a message in AES and it decrypts it too. Im kinda new at this encryption stuff and I'm wondering, where is the seed value it uses and does the seed randomize each time? Because from the looks of it the same String gives different encrypted results.
Thanks.
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import java.io.*;
public class AESGUI extends JPanel {
public static void main(String[] args) {
JFrame frame = new JFrame("AES Encryption");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setPreferredSize(new Dimension(600,300));
frame.setLocationRelativeTo(null);
frame.setResizable(false);
AESGUI p = new AESGUI();
frame.getContentPane().add(p);
frame.pack();
frame.setVisible(true);
}
private JTextField in;
private JTextArea out;
public AESGUI() {
JLabel info = new JLabel("Type any String");
in = new JTextField(20);
JButton encrypt = new JButton("Encrypt");
out = new JTextArea(10,40);
out.setEditable(false);
encrypt.addActionListener(new encryptListener());
in.addActionListener(new encryptListener());
add(info);
add(in);
add(encrypt);
add(out);
add(new JScrollPane(out));
}
private class encryptListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
String data = in.getText();
if (data.length() == 0) { }
else
try {
String en = encrypt(data);
out.append("Encrypted string: " + en + "\n");
out.append("Original String: " + decrypt(en) + "\n\n");
} catch(Exception ex) { }
}
}
public String asHex(byte[] buf) {
StringBuffer strbuf = new StringBuffer(buf.length * 2);
int i;
for (i = 0; i < buf.length; i++) {
if (((int) buf[i] & 0xff) < 0x10)
strbuf.append("0");
strbuf.append(Long.toString((int) buf[i] & 0xff, 16));
}
return strbuf.toString();
}
private SecretKeySpec skeySpec;
private Cipher cipher;
private byte[] encrypted;
public String encrypt(String str) throws Exception {
// Get the KeyGenerator
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128); // 192 and 256 bits may not be available
// Generate the secret key specs.
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
skeySpec = new SecretKeySpec(raw, "AES");
// Instantiate the cipher
cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
encrypted = cipher.doFinal(str.getBytes());
return asHex(encrypted);
}
public String decrypt(String str) throws Exception {
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] original = cipher.doFinal(encrypted);
String originalString = new String(original);
return originalString;
}
}
Without the gui (I hope thats all I removed)
public String asHex(byte[] buf) {
StringBuffer strbuf = new StringBuffer(buf.length * 2);
int i;
for (i = 0; i < buf.length; i++) {
if (((int) buf[i] & 0xff) < 0x10)
strbuf.append("0");
strbuf.append(Long.toString((int) buf[i] & 0xff, 16));
}
return strbuf.toString();
}
private SecretKeySpec skeySpec;
private Cipher cipher;
private byte[] encrypted;
public String encrypt(String str) throws Exception {
// Get the KeyGenerator
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128); // 192 and 256 bits may not be available
// Generate the secret key specs.
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
skeySpec = new SecretKeySpec(raw, "AES");
// Instantiate the cipher
cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
encrypted = cipher.doFinal(str.getBytes());
return asHex(encrypted);
}
public String decrypt(String str) throws Exception {
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] original = cipher.doFinal(encrypted);
String originalString = new String(original);
return originalString;
}
AES comes in 128-bit, 192-bit, and 256-bit implementations, with AES 256 being the most secure.
Although AES key lengths – 128, 192, and 256 bits – may change, the block size of the data encrypted with AES is always 128 bits in size. Out of 128-bit, 192-bit, and 256-bit AES encryption, which progressively use more rounds of encryption for improved security, 128-bit AES encryption is technically the least secure.
The AES Encryption algorithm (also known as the Rijndael algorithm) is a symmetric block cipher algorithm with a block/chunk size of 128 bits. It converts these individual blocks using keys of 128, 192, and 256 bits. Once it encrypts these blocks, it joins them together to form the ciphertext.
For encryption, each round consists of the following four steps: 1) Substitute bytes, 2) Shift rows, 3) Mix columns, and 4) Add round key. The last step consists of XORing the output of the previous three steps with four words from the key schedule.
Yes, it gives different results to the same text, the reason is every time encrypt a message you generate the key.
// Get the KeyGenerator
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128); // 192 and 256 bits may not be available
// Generate the secret key specs.
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
skeySpec = new SecretKeySpec(raw, "AES");
What you can do is, take it out from the the encrypt() method and make it common.
where is the seed value it uses and does the seed randomize each time?
Javadocs are your friend young padawan ;) From your code sample, we see that you are calling keyGenerator.init(int keysize)
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128); // 192 and 256 bits may not be available
And inspecting the javadoc for that method call on that class, we get the following:
Initializes this key generator for a certain keysize. If this key generator requires any random bytes, it will get them using the SecureRandom implementation of the highest-priority installed provider as the source of randomness. (If none of the installed providers supply an implementation of SecureRandom, a system-provided source of randomness will be used.)
In other words, as you originally guessed, a call to init(int keysize)
implies the usage of a randomized seed each time. If you have a particular seed that 1) is good for what you need, and 2) you need to use, then you'll need to use either init(int keysize,SecureRandom random)
, or call [init(SecureRandom random)][4]
alongside your other call to init(int keysize)
.
Hope it helps.
btw, if you would like a deeper introduction to Cryptography, I'd suggest you get Handbook of Applied Cryptography (Discrete Mathematics and Its Applications) by Alfred Menezes, Paul van Oorschot and Scott Vanstone. Though published in 1996, I keep referring to this book all the time over all others.
A book on the theoretical under pinings of Cryptography would be Understanding Cryptography: A Textbook for Students and Practitioners. It is highly mathematical, and this you need if you eventually want to be a cryptographer/cryptanalyst. For overall usage and understanding of cryptographic tools and algorithms, the Menezes et all book mentioned above would be a good start.
For a holistic understanding of computer security topics, I'd suggest Fundamentals of Computer Security Technology by Edward G. Amoroso. For what it's worth, I always take this book with me at work as a reference.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With