RSA Key를 Android Keystore 사용해서 저장하기

AES키를 기기 내부에 저장하는 것도 했으니 RSA도 해봄.

var privateKey : PrivateKey? = null
var publicKey  : PublicKey? = null
var alias = "linsoo.pe.kr"

Keystore 내부에 저장할때 별칭을 가지고 불러올수 있는데 일단 linsoo.pe.kr로 했음.

var ks : KeyStore = KeyStore.getInstance("AndroidKeyStore").apply {
    load(null)
}

키스토어 인스턴스를 가져옵니다.

if(ks.containsAlias(alias)) {
    val entry: KeyStore.Entry = ks.getEntry(alias, null)
    if (entry is KeyStore.PrivateKeyEntry) {
        privateKey = entry.privateKey
        publicKey = entry.certificate.publicKey
    }
}

키스토어내에 alias가 있는지 검색해보고 있으면 가져와서 개인키와 공개키를 뽑아냅니다.

else{
    val kpg = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA,"AndroidKeyStore")
    val parameterSpec = KeyGenParameterSpec.Builder(
        alias,
        KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT
    ).run {
        setAlgorithmParameterSpec(
            RSAKeyGenParameterSpec(
                2048,
                RSAKeyGenParameterSpec.F4
            )
        )
        setBlockModes(KeyProperties.BLOCK_MODE_ECB)
        setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP)
        setDigests(KeyProperties.DIGEST_SHA512)
        setUserAuthenticationRequired(false)
        build()
    }
    kpg.initialize(parameterSpec)
    val keys = kpg.generateKeyPair()
    privateKey = keys.private
    publicKey = keys.public
}

키스토어내에 alias가 없으면 새로 키를 생성합니다. 기본적인건 아니고 다양한 옵션이 있으니 기기 지원버전에 맞게 잘 선택하셔야 합니다.

var text = "동해물과 백두산이"

val oappSp = OAEPParameterSpec(
    "SHA-512",
    "MGF1",
    MGF1ParameterSpec.SHA1,
    PSource.PSpecified.DEFAULT
)
val encCipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-512AndMGF1Padding")
val decCipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-512AndMGF1Padding")
encCipher.init(Cipher.ENCRYPT_MODE,  publicKey, oappSp)
decCipher.init(Cipher.DECRYPT_MODE,  privateKey, oappSp)
var encryptTextByteArray = encCipher.doFinal(text.toByteArray())
var decryptTextByteArray = decCipher.doFinal(encryptTextByteArray)
Log.d("linsoo","원본텍스트 : "+text)
Log.d("linsoo", "암호화 : n"+ String(Base64.encode(encryptTextByteArray, Base64.DEFAULT)))
Log.d("linsoo", "복호화 : "+ String(decryptTextByteArray))

암호화 하고 복호화 하는 부분입니다.
여기서 한가지 삽질했던것이 저 OAEPParameterSpec인데 첫번째 인자는 키 생성시 setDigests 랑 같아야 하고 MFG1ParameterSpec에 SHA는 별개인것입니다.

저는 위에 Digest에서 SHA-512로 해서 둘다 512로 해야 하는건줄 알았는데

“Unsupported MGF1 digest: SHA-512, Only SHA-1 supported” 라는 에러가 뜨더군요. 그래서 두개가 별개값이라는걸 알았습니다 -_-;

RSA Android Keystore 간략하게 정리하면 이렇게 되고 입맛대로 쓰면 될듯 싶습니다.


Comments

“RSA Key를 Android Keystore 사용해서 저장하기”에 대한 2개의 응답

  1. 박종운 아바타

    안녕하세요…
    저는 드론관련 종사자입니다.
    기술적인 문제로 문의를 드리고 싶습니다.
    혹시 괜찬으시면 제 메일로 회신주시면 답변 드리겠습니다.
    감사합니다.

    1. 제가 드론 관련 업무를 안한지 오래되서 도움이 못될거 같습니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다