728x90

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 : $")
}
 

 

 

블로그 이미지

Link2Me

,