RSA 암호화 예제를 찾으니 https://travistran.me/rsa-encryption-in-java-and-javascript-1275/ 가 검색되었다.
이 코드를 코틀린으로 변환하여 테스트 해본 것이다.
앱 build.gradle 추가사항
// RSA 암호화
implementation 'org.bouncycastle:bcpkix-jdk15on:1.56'
implementation 'javax.xml.bind:jaxb-api:2.2.4'
import com.link2me.android.common.TravisRsa.DataTypeEnum import com.link2me.android.common.TravisRsa.ModeEnum import kotlin.Throws import kotlin.jvm.JvmOverloads import com.link2me.android.common.TravisRsa import org.bouncycastle.jce.provider.BouncyCastleProvider import java.io.Serializable import java.lang.Exception import java.nio.charset.StandardCharsets import java.security.KeyFactory import java.security.KeyPairGenerator import java.security.PrivateKey import java.security.PublicKey import java.security.spec.PKCS8EncodedKeySpec import java.security.spec.X509EncodedKeySpec import javax.crypto.Cipher import javax.xml.bind.DatatypeConverter
class TravisRsa : Serializable { enum class ModeEnum { PKCS1, OAEP }
enum class DataTypeEnum { HEX, BASE64 }
var dataType = DataTypeEnum.BASE64 var mode = ModeEnum.PKCS1 var privateKey: PrivateKey? = null var publicKey: PublicKey? = null
constructor() { try { val keyGen = KeyPairGenerator.getInstance("RSA") keyGen.initialize(2048) val pair = keyGen.generateKeyPair() privateKey = pair.private publicKey = pair.public } catch (e: Exception) { } }
constructor(keySize: Int) { try { val keyGen = KeyPairGenerator.getInstance("RSA") keyGen.initialize(keySize) val pair = keyGen.generateKeyPair() privateKey = pair.private publicKey = pair.public } catch (e: Exception) { } }
@Throws(Exception::class) fun encrypt(plainText: String, publicKey: PublicKey?): ByteArray { val cipher = cipher cipher.init(Cipher.ENCRYPT_MODE, publicKey) return cipher.doFinal(plainText.toByteArray(StandardCharsets.UTF_8)) }
@Throws(Exception::class) fun decrypt(cipherText: ByteArray?, privateKey: PrivateKey?): ByteArray { val cipher = cipher cipher.init(Cipher.DECRYPT_MODE, privateKey) return cipher.doFinal(cipherText) }
@JvmOverloads @Throws(Exception::class) fun encrypt( plainText: String, base64PublicKey: String? = getBase64PublicKey(publicKey!!) ): String { val cipherText = encrypt(plainText, getPublicKey(base64PublicKey)) return if (DataTypeEnum.BASE64 == dataType) { toBase64(cipherText) } else { toHex(cipherText) } }
@JvmOverloads @Throws(Exception::class) fun decrypt( cipherText: String?, base64PrivateKey: String? = getBase64PrivateKey(privateKey!!) ): String { val cipherBytes: ByteArray cipherBytes = if (DataTypeEnum.BASE64 == dataType) { fromBase64(cipherText) } else { fromHex(cipherText) } return String(decrypt(cipherBytes, getPrivateKey(base64PrivateKey)), StandardCharsets.UTF_8) }
@get:Throws(Exception::class) private val cipher: Cipher private get() = if (ModeEnum.OAEP == mode) { Cipher.getInstance( "RSA/ECB/OAEPWithSHA1AndMGF1Padding", BouncyCastleProvider() ) } else { Cipher.getInstance("RSA/ECB/PKCS1Padding") }
companion object {
fun getBase64PublicKey(publicKey: PublicKey): String { return toBase64(publicKey.encoded) }
fun getBase64PrivateKey(privateKey: PrivateKey): String { return toBase64(privateKey.encoded) }
fun getPublicKey(base64PublicKey: String?): PublicKey? { try { val keySpec = X509EncodedKeySpec(fromBase64(base64PublicKey)) return KeyFactory.getInstance("RSA").generatePublic(keySpec) } catch (e: Exception) { } return null }
fun getPrivateKey(base64PrivateKey: String?): PrivateKey? { try { val keySpec = PKCS8EncodedKeySpec(fromBase64(base64PrivateKey)) return KeyFactory.getInstance("RSA").generatePrivate(keySpec) } catch (e: Exception) { } return null }
private fun fromBase64(str: String?): ByteArray { return DatatypeConverter.parseBase64Binary(str) }
private fun toBase64(ba: ByteArray): String { return DatatypeConverter.printBase64Binary(ba) }
private fun fromHex(str: String?): ByteArray { return DatatypeConverter.parseHexBinary(str) }
private fun toHex(ba: ByteArray): String { return DatatypeConverter.printHexBinary(ba) } } }
fun main(args: Array<String>) { val input = "안녕하세요. 반갑습니다." println(input.length) println("byte array length=" + input.toByteArray().size)
val travisRsa = TravisRsa() val encrypted = travisRsa.encrypt(input) val decrypted = travisRsa.decrypt(encrypted)
println("encrypted : $") println("decrypted : $") }
|