In order to prevent security issue, we need to secure the data transfer by encrypt the some credentials data such as card number, cvv and expiry.
How to encrypt the data:
PBKDF2.kt
package ph.safibank.cardmanager.util import javax.crypto.SecretKeyFactory import javax.crypto.spec.PBEKeySpec class PBKDF2 { private fun doEncrypt(password: CharArray, salt: ByteArray): ByteArray? { val skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256") val spec = PBEKeySpec(password, salt, 10000, 256) val key = skf.generateSecret(spec) return key.encoded } fun encrypt(salt: String, payload: CharArray): ByteArray? { return doEncrypt(payload, salt.toByteArray()) } }
Encrypt.kt
package ph.safibank.cardmanager.util import java.util.Base64 import javax.crypto.Cipher import javax.crypto.spec.IvParameterSpec import javax.crypto.spec.SecretKeySpec data class EncryptedData( val data: String, val iv: String ) class Encrypt( private val salt: String ) { private val pbkdf2 = PBKDF2() private fun generateKey(secret: String): SecretKeySpec { return SecretKeySpec(pbkdf2.encrypt(salt, secret.toCharArray()), "AES") } fun encrypt(secret: String, payload: String): EncryptedData { val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding") cipher.init(Cipher.ENCRYPT_MODE, generateKey(secret)) val algParam = cipher.parameters val iv = algParam.getParameterSpec(IvParameterSpec::class.java).iv val encryptedData = cipher.doFinal(payload.toByteArray()) val base64Encoder = Base64.getEncoder() return EncryptedData( base64Encoder.encodeToString(encryptedData), base64Encoder.encodeToString(iv) ) } fun decrypt(secret: String, data: EncryptedData): String { val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding") val base64Decoder = Base64.getDecoder() cipher.init(Cipher.DECRYPT_MODE, generateKey(secret), IvParameterSpec(base64Decoder.decode(data.iv))) val decrypted = cipher.doFinal(base64Decoder.decode(data.data)) return String(decrypted) } }
Example:
import ph.safibank.cardmanager.util.Encrypt fun main() { val password = "anypassword" // PBKDF2 salt val secret = "anysecret" // AES secret val payload = "top secret data" val encrypter = Encrypter(passowrd) val encryptedData = encrypter.encrypt(secret, payload) // should return data and IV val decryptedData = encrypter.decrypt(secret, encryptedData) // should return log.info("encrypted data: $encryptedData") log.info("decrypted data: $decryptedData") }
result:
encrypted data: EncryptedData(data=gxR5Z+tr2Ygn+58vh1VTIA==, iv=wjUXX3WJkjJCDYhPCJv0rg==) decrypted data: top secret data