Created
February 6, 2025 15:45
-
-
Save asjadoun/5df1efb2e3bbb359e764550b7d6039dc to your computer and use it in GitHub Desktop.
Encrypt sensitive data like PII or financial information
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import io.github.nremond.PBKDF2 | |
import java.security.{MessageDigest, SecureRandom} | |
import javax.crypto.SecretKeyFactory | |
import javax.crypto.spec.PBEKeySpec | |
import java.util.Base64 | |
import java.security.* | |
import java.util.Base64 | |
import javax.crypto.* | |
import java.security.SecureRandom | |
import javax.crypto.SecretKeyFactory | |
import javax.crypto.spec.PBEKeySpec | |
import javax.crypto.Cipher | |
import javax.crypto.spec.SecretKeySpec | |
object PIIEncryptionApp { | |
def main(args: Array[String]): Unit = { | |
val sensitiveData = "Sensitive Data" | |
// Example 1 | |
val pii = new PiiEncryption() | |
val encryptedData = pii.encrypt(sensitiveData) | |
println(s"decryptedData: ${pii.decrypt(encryptedData)}") | |
// Example 2 | |
val password = "my_secure_password" | |
val salt = PBKDF2Util.generateSalt(16) | |
val secretKey = PBKDF2Util.deriveKey(password, salt, 65536, 256) | |
val encryptedData2 = PBKDF2Util.encrypt(sensitiveData, secretKey) | |
val decryptedData2 = PBKDF2Util.decrypt(encryptedData2, secretKey) | |
println(s"decryptedData: ${new String(decryptedData2)}") | |
// Example 3 | |
// val salt = new Array[Byte](16) | |
// new SecureRandom().nextBytes(salt) | |
val iterations = 100000 | |
val keyLength = 32 | |
val cryptoAlgo = "HmacSHA512" // "HmacSHA256" // "HmacSHA1" | |
val derivedKey = | |
PBKDF2(password = password.getBytes("UTF-8"), salt = salt, iterations = iterations, dkLength = keyLength, cryptoAlgo = cryptoAlgo) | |
val pbkdf2SecretKey = new SecretKeySpec(derivedKey, "AES") | |
val pbkdf2ScalaExample = new PBKDF2ScalaExample | |
val pbkdf2EncryptedData = pbkdf2ScalaExample.encrypt(sensitiveData, pbkdf2SecretKey) | |
val pbkdf2DecryptedData = pbkdf2ScalaExample.decrypt(pbkdf2EncryptedData, pbkdf2SecretKey) | |
println(s"decryptedData: $pbkdf2DecryptedData") | |
} | |
} | |
class PBKDF2ScalaExample { | |
def encrypt(data: String, secretKey: SecretKeySpec): String = { | |
val cipher = Cipher.getInstance("AES") | |
cipher.init(Cipher.ENCRYPT_MODE, secretKey) | |
Base64.getEncoder.encodeToString(cipher.doFinal(data.getBytes("UTF-8"))) | |
} | |
def decrypt(encryptedData: String, secretKey: SecretKeySpec): String = { | |
val cipher = Cipher.getInstance("AES") | |
cipher.init(Cipher.DECRYPT_MODE, secretKey) | |
new String(cipher.doFinal(Base64.getDecoder.decode(encryptedData)), "UTF-8") | |
} | |
} | |
object PBKDF2Util { | |
def generateSalt(length: Int): Array[Byte] = { | |
val salt = new Array[Byte](length) | |
new SecureRandom().nextBytes(salt) | |
salt | |
} | |
def deriveKey(password: String, salt: Array[Byte], iterations: Int, keyLength: Int): SecretKeySpec = { | |
val keySpec = new PBEKeySpec(password.toCharArray, salt, iterations, keyLength) | |
val keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256") | |
val keyBytes = keyFactory.generateSecret(keySpec).getEncoded | |
new SecretKeySpec(keyBytes, "AES") | |
} | |
def encrypt(data: String, secretKey: SecretKeySpec): Array[Byte] = { | |
val cipher = Cipher.getInstance("AES") | |
cipher.init(Cipher.ENCRYPT_MODE, secretKey) | |
cipher.doFinal(data.getBytes("UTF-8")) | |
} | |
def decrypt(encryptedData: Array[Byte], secretKey: SecretKeySpec): String = { | |
val cipher = Cipher.getInstance("AES") | |
cipher.init(Cipher.DECRYPT_MODE, secretKey) | |
new String(cipher.doFinal(encryptedData), "UTF-8") | |
} | |
} | |
class PiiEncryption { | |
val algorithm = "AES" //AES/CBC/PKCS5Padding | |
val key = generateSecretKey(algorithm) | |
def encrypt(data: String): String = { | |
val cipher = Cipher.getInstance(algorithm) | |
cipher.init(Cipher.ENCRYPT_MODE, key) | |
val encryptedBytes = cipher.doFinal(data.getBytes) | |
Base64.getEncoder.encodeToString(encryptedBytes) | |
} | |
def decrypt(encryptedData: String): String = { | |
val cipher = Cipher.getInstance(algorithm) | |
cipher.init(Cipher.DECRYPT_MODE, key) | |
val decryptedBytes = cipher.doFinal(Base64.getDecoder.decode(encryptedData)) | |
new String(decryptedBytes, "UTF-8") | |
} | |
private def generateSecretKey(algo: String): SecretKey = { | |
val keyGen = KeyGenerator.getInstance(algo) | |
keyGen.init(256) // 256-bit AES key | |
keyGen.generateKey() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment