I am trying to learn and test the java 1.6 encryption/decryption API. I want to know what I am doing wrong and what I am missing in terms of knowledge.
In the code that follows below, I create two ciphers: one to encrypt and another to decrypt. When I use these ciphers, I initialize them with different SecretKey's, but I am still able to get the same value back out. Why is this?
String algorithm = "DES";
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(algorithm);
byte[] encBytes = "12345678".getBytes("UTF8");
byte[] decBytes = "56781234".getBytes("UTF8");
DESKeySpec keySpecEncrypt = new DESKeySpec(encBytes);
DESKeySpec keySpecDecrypt = new DESKeySpec(decBytes);
SecretKey keyEncrypt = keyFactory.generateSecret(keySpecEncrypt);
SecretKey keyDecrypt = keyFactory.generateSecret(keySpecDecrypt);
Cipher cipherEncrypt = Cipher.getInstance(algorithm);
Cipher cipherDecrypt = Cipher.getInstance(algorithm);
String input = "john doe";
cipherEncrypt.init(Cipher.ENCRYPT_MODE, keyEncrypt);
byte[] inputBytes = cipherEncrypt.doFinal(input.getBytes());
System.out.println("inputBytes: " + new String(inputBytes));
cipherDecrypt.init(Cipher.DECRYPT_MODE, keyDecrypt);
byte[] outputBytes = cipherDecrypt.doFinal(inputBytes);
System.out.println("outputBytes: " + new String(outputBytes));
You need to use the same IV for encryption and decryption.
Two types of encryption algorithms can be used by the encryption key server: symmetric algorithms and asymmetric algorithms. Symmetric, or secret key encryption, uses a single key for both encryption and decryption.
The symmetric-key block cipher plays an important role in data encryption. It means that the same key is used for both encryption and decryption. The Advanced Encryption Standard (AES) is a widely used symmetric-key encryption algorithm.
Data encrypted with hashing cannot be deciphered or reversed back into its original form. That's why hashing is used only as a method of verifying data.
Welcome to encryption! As mentioned DES is symmetric and requires the same key for encryption as decryption. That key needs to be the right number of bits for the cipher that you're using. For DES that's 56-bit. Before you go too far with that though, here are a few things you might want to consider:
Here's a working example of using 128-bit AES encryption in CBC mode with PKCS #5 padding:
import java.security.MessageDigest;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class EncryptDecrypt {
public static void main(String[] args) throws Exception {
// here are your inputs
String keyString = "averylongtext!@$@#$#@$#*&(*&}{23432432432dsfsdf";
String input = "john doe";
// setup AES cipher in CBC mode with PKCS #5 padding
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
// setup an IV (initialization vector) that should be
// randomly generated for each input that's encrypted
byte[] iv = new byte[cipher.getBlockSize()];
new SecureRandom().nextBytes(iv);
IvParameterSpec ivSpec = new IvParameterSpec(iv);
// hash keyString with SHA-256 and crop the output to 128-bit for key
MessageDigest digest = MessageDigest.getInstance("SHA-256");
digest.update(keyString.getBytes());
byte[] key = new byte[16];
System.arraycopy(digest.digest(), 0, key, 0, key.length);
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
// encrypt
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
byte[] encrypted = cipher.doFinal(input.getBytes("UTF-8"));
System.out.println("encrypted: " + new String(encrypted));
// include the IV with the encrypted bytes for transport, you'll
// need the same IV when decrypting (it's safe to send unencrypted)
// decrypt
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
byte[] decrypted = cipher.doFinal(encrypted);
System.out.println("decrypted: " + new String(decrypted, "UTF-8"));
}
}
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