-
-
Save itarato/abef95871756970a9dad to your computer and use it in GitHub Desktop.
package com.company; | |
import javax.crypto.Cipher; | |
import javax.crypto.Mac; | |
import javax.crypto.spec.IvParameterSpec; | |
import javax.crypto.spec.SecretKeySpec; | |
import java.security.MessageDigest; | |
import java.security.SecureRandom; | |
public class Main { | |
public static void main(String[] args) throws Exception { | |
String key = "abcdefghijklmop"; | |
String clean = "Quisque eget odio ac lectus vestibulum faucibus eget."; | |
byte[] encrypted = encrypt(clean, key); | |
String decrypted = decrypt(encrypted, key); | |
} | |
public static byte[] encrypt(String plainText, String key) throws Exception { | |
byte[] clean = plainText.getBytes(); | |
// Generating IV. | |
int ivSize = 16; | |
byte[] iv = new byte[ivSize]; | |
SecureRandom random = new SecureRandom(); | |
random.nextBytes(iv); | |
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv); | |
// Hashing key. | |
MessageDigest digest = MessageDigest.getInstance("SHA-256"); | |
digest.update(key.getBytes("UTF-8")); | |
byte[] keyBytes = new byte[16]; | |
System.arraycopy(digest.digest(), 0, keyBytes, 0, keyBytes.length); | |
SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES"); | |
// Encrypt. | |
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); | |
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec); | |
byte[] encrypted = cipher.doFinal(clean); | |
// Combine IV and encrypted part. | |
byte[] encryptedIVAndText = new byte[ivSize + encrypted.length]; | |
System.arraycopy(iv, 0, encryptedIVAndText, 0, ivSize); | |
System.arraycopy(encrypted, 0, encryptedIVAndText, ivSize, encrypted.length); | |
return encryptedIVAndText; | |
} | |
public static String decrypt(byte[] encryptedIvTextBytes, String key) throws Exception { | |
int ivSize = 16; | |
int keySize = 16; | |
// Extract IV. | |
byte[] iv = new byte[ivSize]; | |
System.arraycopy(encryptedIvTextBytes, 0, iv, 0, iv.length); | |
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv); | |
// Extract encrypted part. | |
int encryptedSize = encryptedIvTextBytes.length - ivSize; | |
byte[] encryptedBytes = new byte[encryptedSize]; | |
System.arraycopy(encryptedIvTextBytes, ivSize, encryptedBytes, 0, encryptedSize); | |
// Hash key. | |
byte[] keyBytes = new byte[keySize]; | |
MessageDigest md = MessageDigest.getInstance("SHA-256"); | |
md.update(key.getBytes()); | |
System.arraycopy(md.digest(), 0, keyBytes, 0, keyBytes.length); | |
SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES"); | |
// Decrypt. | |
Cipher cipherDecrypt = Cipher.getInstance("AES/CBC/PKCS5Padding"); | |
cipherDecrypt.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec); | |
byte[] decrypted = cipherDecrypt.doFinal(encryptedBytes); | |
return new String(decrypted); | |
} | |
} |
Nice job !
i ma doing a thesis work in my base paper i got this concept
FileEncrypt(File)—It encrypts the File with Convergent Encryption using 256-bit AES algorithm in cipher block chaining (CBC) mode, where the con-vergent key is from SHA-256 Hashing of the file
so is this code is relly helps me ?
// Hashing key.
MessageDigest digest = MessageDigest.getInstance("SHA-256");
digest.update(key.getBytes("UTF-8"));
byte[] keyBytes = new byte[16];
System.arraycopy(digest.digest(), 0, keyBytes, 0, keyBytes.length);
SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES");
This is really not a good way to derive a key. Look into proper KDF like HKDF: https://en.wikipedia.org/wiki/HKDF
but sir block diagram of CBC says iv should be added with original text and then need to be encrypted
Thank you for that!
I think the following is more secure for generating secret key from password:
KeySpec spec = new PBEKeySpec(pass.toCharArray(), salt, 65536, 256); SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); byte[] secKey = f.generateSecret(spec).getEncoded(); SecretKeySpec secretKeySpec = new SecretKeySpec(secKey, "AES");
@tsk0707
This code is working fine in this way. Like there is the main method and from that main method encrypt and decrypt both methods are getting called in single-shot so it's working fine as we are passing combined IV and encrypted text at a time in decrypt method. But how to handle this in real-life projects. For Example in my project, there is a mechanism like while Create Partner method is called, data should be encrypted and saved in the database. When I call the Get Partner method that encrypted data come back and it needs to be decrypted and returned to the client. Now, In my case, while decrypting how to get that combination of IV and Encrypted Bytes? Here we can not call encrypt method again because to call encrypt method we need plaintext which is already encrypted and stored in the database when we called Create method. So, here I got stuck while decryption process. Please do the needful.
Thank you!
However, there seems to be a mistake in the code:
MessageDigest digest = MessageDigest.getInstance("SHA-256");
digest.update(key.getBytes("UTF-8"));
byte[] keyBytes = new byte[16];
System.arraycopy(digest.digest(), 0, keyBytes, 0, keyBytes.length);
The digest is 32 bytes long, not 16! The code cuts off half of the key.
The fix is simple:
byte[] keyBytes = new byte[32];
nice