I am trying to encode a String
so I can store it safely in my database. Most password encoders, like bcrypt, can only hash your String
, with no way of getting it back (which for a password makes sense), and I want to decode it when I retrieve the information from my database.
I tried using org.springframework.security.crypto.encrypt.Encryptors.queryableText()
but the method is deprecated.
Is there any other way to do it?
CodePudding user response:
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
public class CryptoManager {
//Key for encryption and decryption
public static final byte[] KEY =
{118, 106, 107, 122, 76, 99, 69, 83, 101, 103, 82, 101, 116, 75, 101, 127};
public static void main(String args[]) {
String salt = "HELLO";
String encryptedString = encrypt(salt, "HelloWorld12345");
System.out.println("Encripted string is " encryptedString);
String decryptedString = decrypt(salt, encryptedString);
System.out.println("Decrypted string is " decryptedString);
}
public static String encrypt(String salt, String plainText) {
if (plainText == null || plainText.isEmpty()) {
System.out.println("No data to encrypt!");
return plainText;
}
Cipher cipher = null;
String encryptedString = "";
try {
// Creating a Cipher object
cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
// Creating a secret key from KEY byte array
final SecretKeySpec secretKey = new SecretKeySpec(KEY, "AES");
// Initializing a Cipher object
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
// Encrypting the plain text string
byte[] encryptedText = cipher.doFinal(salt.concat(plainText).getBytes());
// Encoding the encrypted text to Base64
encryptedString = Base64.getEncoder().encodeToString(encryptedText);
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException
| IllegalBlockSizeException | BadPaddingException ex) {
System.out.println("Exception caught while encrypting : " ex);
}
return encryptedString;
}
public static String decrypt(String salt, String cipherText) {
if (cipherText == null || cipherText.isEmpty()) {
System.out.println("No data to decrypt!");
return cipherText;
}
String decryptedString = "";
Cipher cipher = null;
try {
// Creating a Cipher object
cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
// Creating a secret key from KEY byte array
final SecretKeySpec secretKey = new SecretKeySpec(KEY, "AES");
// Initializing a Cipher object
cipher.init(Cipher.DECRYPT_MODE, secretKey);
// Decoding from Base64
byte[] encryptedText = Base64.getDecoder().decode(cipherText.getBytes());
// Decrypting to plain text
decryptedString = new String(cipher.doFinal(encryptedText));
} catch (NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException
| IllegalBlockSizeException | BadPaddingException ex) {
System.out.println("Exception caught while decrypting : " ex);
}
return decryptedString.replace(salt, "");
}
}
Check this out for more detail
CodePudding user response:
Since you want to store the data securely in database, what you really need to do is encrypt the data before writing to database from application.
To encrypt/decrypt the data from application you can use Symmetric key algorithm like AES.
To automatically convert this in entity you can add a converter in corresponding column
@Convert(converter = DataEncryptDecryptConverter.class)
@Column(name = "DATA")
private String data;
And the converter
@Converter
@Component
public class DataEncryptDecryptConverter implements AttributeConverter<String, String> {
@Override
public String convertToDatabaseColumn(String attribute) {
// Code to encrypt data
}
@Override
public String convertToEntityAttribute(String dbData) {
// Code to decrypt data
}
}