Skip to content

Instantly share code, notes, and snippets.

@sadhasivam
Created April 25, 2020 17:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sadhasivam/656f86dd7619cf22fcedd3cff364ed79 to your computer and use it in GitHub Desktop.
Save sadhasivam/656f86dd7619cf22fcedd3cff364ed79 to your computer and use it in GitHub Desktop.
AES/RSA_Decryption
import org.bouncycastle.jce.provider.BouncyCastleProvider
import java.io.File
import java.security.KeyFactory
import java.security.interfaces.RSAPrivateKey
import java.security.spec.AlgorithmParameterSpec
import java.security.spec.PKCS8EncodedKeySpec
import java.util.Base64
import javax.crypto.Cipher
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec
data class CryptoPayload(
val cipherText: String,
val ivParam: String,
val aesKey: String,
val isKeyRSAEncrypted: Boolean = true,
val privateRSKey: RSAPrivateKey?
)
const val ALGORITHM = "AES"
fun main(args: Array<String>) {
// You need BounceCastle Lib for now
// compile "org.bouncycastle:bcpkix-jdk15on:1.59"
//. This is the key you get from DynamoDB
var privateKey = File("src/main/resources/pik_rsa_private_key.pem").readText()
privateKey = privateKey.replace("-----BEGIN RSA PRIVATE KEY-----\n", "")
privateKey = privateKey.replace("-----END RSA PRIVATE KEY-----", "")
privateKey = privateKey.replace("\n", "")
// This is data you get from EC Modal /JsSaveChargeCard
// Form Data Mapping
// CrypoPayload.cipherText is mapped to encrypted form value
// CrypoPayload.ivParam is mapped to iv form value
// CrypoPayload.aesKey is mapped to key form value
val cryptoPayloadEC = CryptoPayload(
cipherText = "7Zd6Q/Fr3JD6+c7Ne6T6Q9NSPprk0XciyApKENkJ9TU/HQNPT6AUZhC0GisQ8yu0/Hjz3gjyXfMkm+GGsHyutZCWjMkUNUcw2sDXMM717wbLvYqLeDK3uoMVZCaOMtf7ss+EZWN57FaLxwNhovSflA==",
ivParam = "FiOWmsebW5u+8CreCiOW5g==",
aesKey = "IeZ4OMTPbRHBKE3cik2HBXbP9n5OwG+DaLtCcN1K73MfKZ4URsGN8Ts4k2wEfp9eMnQY7VYH627Ekt9eGJ1wgknHVHIdmSP6dhrNneIYX+BnDnPxLvIwqkLmfLZ+ZADoGPPNfE1nrFphxD0pxllbZry3QzmXwd2VLDZZ7kGHuvDqsPM0HqP36DwtUB5OLYUnItFV1yoKsy4AF/kbpb4HDAQQY8qxsNmYsnRIQc4+sJge3G4i77RK9kkpxWWoCa81teQFcjapp2LdGVYz29bPArFlIkpGYTKX0IVM8nrAK+DJu68eYLF1rZlNCKA2lipt55YRWL2AJvg/AUM4ZKOA4w==",
isKeyRSAEncrypted = true,
privateRSKey = getPrivateRSAKey(privateKey)
)
var transformationMode = "AES/CBC/PKCS5Padding";
decryptDefault(cryptoPayloadEC, transformationMode)
}
fun decryptDefault(cryptoPayload: CryptoPayload, transformationMode: String): String? {
var decryptedValue: String? = null
val base64Decoder = Base64.getDecoder()
var aesKey = cryptoPayload.aesKey
try {
aesKey = base64DecodeAndRSADecrypt(cryptoPayload.aesKey, cryptoPayload.privateRSKey!!)
val ivParamByteArray = base64Decoder.decode(cryptoPayload.ivParam)
val paramSpec: AlgorithmParameterSpec = IvParameterSpec(ivParamByteArray)
val key = SecretKeySpec(base64Decoder.decode(aesKey), ALGORITHM)
val cipher = Cipher.getInstance(transformationMode)
cipher.init(Cipher.DECRYPT_MODE, key, paramSpec)
val binaryData = cipher.doFinal(base64Decoder.decode(cryptoPayload.cipherText))
decryptedValue = String(binaryData).trim { it <= ' ' }
} catch (e: Exception) {
e.printStackTrace()
}
val logFmt = """
============================================================
AES KEY: $aesKey
Init Vector: ${cryptoPayload.ivParam}
Cipher Text: ${cryptoPayload.cipherText}
Transaction Mode: $transformationMode
Decrypted Value: $decryptedValue
============================================================
""".trimIndent()
println(logFmt)
return decryptedValue
}
fun getPrivateRSAKey(base64EncodedRSAPrivateKey: String): RSAPrivateKey {
var base64Decoder: Base64.Decoder = Base64.getDecoder()
val privateKeyBytes = base64Decoder.decode(base64EncodedRSAPrivateKey)
val provider = BouncyCastleProvider()
val keySpec = PKCS8EncodedKeySpec(privateKeyBytes)
return KeyFactory.getInstance("RSA", provider).generatePrivate(keySpec) as RSAPrivateKey
}
fun base64DecodeAndRSADecrypt(base64EncodedCiphexText: String, privateRSAKey: RSAPrivateKey): String {
return String(decryptRSA(base64EncodedCiphexText, privateRSAKey))
}
fun decryptRSA(base64EncodedCiphexText: String, privateRSAKey: RSAPrivateKey): ByteArray {
var base64Decoder: Base64.Decoder = Base64.getDecoder()
val securityProvider = BouncyCastleProvider()
val cipher = Cipher.getInstance("RSA/None/PKCS1Padding", securityProvider)
cipher.init(Cipher.DECRYPT_MODE, privateRSAKey)
return cipher.doFinal(base64Decoder.decode(base64EncodedCiphexText))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment