이번 글에서는 안드로이드에서 X.509인증서와 CRL을 받아와서 사용해보도록 하자.
X.509인증서와 CRL에 대한 내용은 생략하도록 하고, 두 데이터는 전달 받을 때 pem형식으로 받아온다.
pem형식은 아래와 같이 되어있다.
-----BEGIN CERTIFICATE-----
MIIDizCCAnOgAwIBAgIUS8lUTmZGBA+IbTMGkCLVKT6RdMYwDQYJKoZIhvcNAQEL
BQAwNjELMAkGA1UEBhMCa3IxEzARBgNVBAoMClN1d29uVW5pdi4xEjAQBgNVBAMM
CXJvb3RjYVlTWTAeFw0yMTA2MDIyMjEzMDBaFw0yMjA2MDIyMjEzMDBaMDExCzAJ
BgNVBAYTAmtyMRIwEAYDVQQKDAlTdXdvblVuaXYxDjAMBgNVBAMMBTY1OTc5MIIB
IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwebQzxF0TOmF2fHI/4y5UobD
rbHFLtgniBxtr6nVkgdbzde6i4Zep8Od7l2LBwIyu29Atavnh6Aahrq4/cw3hT4W
GsxA/yD4MOc8L2+BzlkvFqzuznhF3wBRlU1qmiFbLovI0oPE/I+EGg8OrICFY+I6
oYQYKQKLBjGaZ3QrtfJleJYC0dYC4myZWg/26D0PAodfg5g8fjAaClGhrHvs8Tta
P6b7fR1mWUYbc+S23775hovI3I0h4eYuo3CCkkYmapFpBL8G0eb/x8j4tPU7sA7j
ChHfPHP9/tp1okx2445Z6OEuI+2twVg0sCwUWbljk0NgJhI16wvUeDl+zx1wTwID
AQABo4GVMIGSMAkGA1UdEwQCMAAwHwYDVR0jBBgwFoAUv2QeVPfLh9E2hEUSAK53
bEiBNcYwHQYDVR0OBBYEFNeo0v1pjEwUFUjH4JXX5rbS62WpMAsGA1UdDwQEAwIF
4DAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3
Lnplcm9ucy5jb20wDQYJKoZIhvcNAQELBQADggEBAFR8Z7cyFPZkeHJo/rN4rMpI
HaQHmGAzFD5z2DzHJ3qvTMEWL+EokvS/t0j5VkwLYVbkVULCl2ZqwRR4cTv4VZlT
+wqcJiapDlTlzB5GPquydDVLl/9Cr9W0/LPpC6Q9E6bxP48rskuJTjaoA1aZG3rG
K2z5rZLXFzF9pVHQ+heCDkA/mMFb6DHIutoOQgnzigFMcEjyWmnoPeHr1VM6X/TO
/AR1NKR+IsoGZMdMc+pIdBMwPs3zwXNPC4wyK5jGmL1BnDJJmEnpJJMIC+OvQKZ1
25gB8g6MwQPA515G6q70gLTynTniCRM+mg9ldX7TpFEycVXn/YOlm+/RYyYFOOc=
-----END CERTIFICATE-----
데이터를 받아올 때에는 안드로이드의 retrofit을 통해 get형태로 받아올것이다.
이렇게 get으로 받아온 데이터를 각각 용도에 맞게 X.509 Certificate또는 CRL로 만들어주어야 한다.
방법은 매우 간단하다.
먼저 X509 Certificate부터 확인해보자
fun saveCertificate(certificate: String, path: File?, crl: X509CRL){
if(path != null){
var tempFile = File(path, "certificate.crt")
try{
val writer = FileWriter(tempFile)
val buffer = BufferedWriter(writer)
buffer.write(certificate)
buffer.close()
}catch(e: java.lang.Exception){
e.printStackTrace()
}
var cf = CertificateFactory.getInstance("X.509")
var caIn = BufferedInputStream(FileInputStream(tempFile))
var ca = caIn.use{
cf.generateCertificate(it) as X509Certificate
}
var kf = KeyFactory.getInstance("RSA")
var public = kf.generatePublic(X509EncodedKeySpec(ca.publicKey.encoded))
try{
if(checkValidify(ca, public, crl)){
App.prefs.publicKey = Base64Utils.encode(public.encoded)
}
}catch (e: Exception){
Log.e("인증서 유효성 검사", "CRL목록을 받아오지 못했습니다.")
e.printStackTrace()
}
}
}
이 글에선 데이터를 받아서 certficiate.crt파일에 저장해주도록 하였다.
가장 먼저 pem형식으로 된 인증서 내용을 String으로 받게된다.
이후 certificateFactory객체를 만드는데, Instance는 X.509를 지정해준다.
위에서 받은 인증서 데이터(String)을 FileInputStream을 사용해 파일에 써주도록 한다.
그리고 이 String을 X509Certificate 객체로 바꾸어주어야하는데,
이때는 위에서 생성한 certificateFactory객체에서 generateCertificate메소드를 사용해서 만들어준다.
이 메소드에 argument로 caIn이 들어가게되고, 이 데이터를 X509Certificate로 캐스트해준다.
실제로 인증서를 사용할 때에는 인증서 유효성 검사를 진행해야한다.
인증서 유효성 검사는 인증서 유효기간 검사 -> 인증서 폐기목록(CRL)확인 -> CA의 서명 확인 순으로 진행된다.
다음은 CRL을 객체로 만들어 사용하는 법에 대해서 알아보자.
fun saveCRL(response: String?, path: File?): X509CRL{
var tempFile = File(path, "CRL.crl")
try{
val writer = FileWriter(tempFile)
val buffer = BufferedWriter(writer)
buffer.write(response)
buffer.close()
}catch(e: java.lang.Exception){
e.printStackTrace()
}
val cf = CertificateFactory.getInstance("X.509")
val crlIn = BufferedInputStream(FileInputStream(tempFile))
val crl = crlIn.use{
cf.generateCRL(it) as X509CRL
}
try{
crl.verify(getCAPublicKey())
}catch (e: Exception){
Log.e("CRL 서명 검증", "실패")
}
return crl
}
여기서도 위와 마찬가지로 CRL을 pem형식으로 받아오고, 이를 파일에 저장해줄것이다.
사실상 코드는 거의다 비슷한데 cf.generateCRL메소드를 사용하고, 이를 X509CRL로 캐스트해준다는 부분만 다르다.
CRL을 사용할 때에도 CA의 서명을 검증해야한다.
'안드로이드 > 개발관련(Kotlin)' 카테고리의 다른 글
안드로이드에서 공용키 암호화(RSA) 사용하기(Kotlin) (0) | 2023.02.27 |
---|---|
안드로이드 Sha256 Hash화 (0) | 2023.02.27 |
라이브러리 목록 (0) | 2022.09.01 |
안드로이드 권한(Permisson) 요청 (0) | 2022.02.08 |
안드로이드 View에 외곽선(테두리) 추가하는 법 (0) | 2022.01.24 |