반응형
이번엔 앱의 보안에 대해서 조치를 취하다가 간단한 자동 로그아웃을 구현하려고 합니다.
비밀번호가 없는 네트워크나 "WEP" 보안형식의 네트워크일 경우를 체크해서 AlertDialog창을 띄운다거나, 로그아웃 예정 메시지를 알려주는 거죠.
0 간단한 내용
1. 전부 AOS 운영체제의 service딴으로 접근하는거라 의존성 추가는 필요 X
2. 별도의 class로 분리해서 화면전환 시 빠르게 사용하려고 구현했구요
1. WifiManager.kt
class WifiManager(private val context: Context) {
...
}
비전공자로 기본 토대가 조금 부족하다고 느꼈는데, 클린 코드에서 코드의 재사용성을 높이기 위해 object와 class를 만들어 사용할 때 뭔 차이일까.. 싶었는데
이 부분에서 context가 필요하고? class를 통해서 init으로 별도의 unit으로 분리해서 사용하려면 class, 그냥 함수의 집합으로써, 각 화면에서 init하지 않고 그냥 import해서 쓰면 object??
아무튼, 둘 다 기능 구현을 위해 빠르게 fragment나 activity에서 구현했던 코드들을 분리할 때, 어떤 형식으로 분리해야할까에 대해서 조금 더 기준을 잡게 된 느낌
1) WifiManager
// WifiManager.kt
private val wifiManager: WifiManager =
context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
getSystemService를 통해 운영체제의 WIFI_SERVICE를 가져옴
// WIfiManager.kt
@SuppressLint("MissingPermission")
fun checkWifiSecurity(): String {
val wifiInfo: WifiInfo = wifiManager.connectionInfo
val networkId = wifiInfo.networkId
val configurations = wifiManager.configuredNetworks
// 연결된 네트워크의 보안 설정 확인
val securityType = configurations?.find { it.networkId == networkId }?.let {
getSecurityType(it)
} ?: "UNKNOWN"
if (securityType == "WEP") {
// WEP 네트워크에 연결된 경우 경고 표시
Toast.makeText(context, "현재 연결된 Wi-Fi는 보안에 취약한 WEP 암호화를 사용합니다.", Toast.LENGTH_LONG).show()
}
return securityType
}
private fun getSecurityType(configuration: WifiConfiguration): String {
return when {
configuration.wepKeys[0] != null -> "WEP"
configuration.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_PSK) -> "WPA/WPA2"
configuration.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.NONE) -> "OPEN"
else -> "UNKNOWN"
}
}
wifiManager의 연결 정보를 가져오고
networkId를 가져와서 configuredNetworks에서 연결된 네트워크를 매칭해서
getSecurityType을 통해 가져옴.
WEP | WPA/WPA2 |
유선 동등 프라이버시(Wired Equivalent Privacy, WEP)는 무선랜 표준을 정의하는 IEEE 802.11 규약의 일부분으로 무선 LAN 운용간의 보안을 위해 사용되는 알고리즘이다. 1997년 재정된 802.11 표준에서 도입되었던 WEP는 전통적인 유선 네트워크와 비슷한 데이터 보안성을 제공하기 위해 만들어졌다. 10자리 또는 26자리의 16진수 키값을 사용하는 WEP는, 한때 매우 보편적으로 사용되었으며 라우터의 보안 설정에서 가장 우선적으로 표시되는 옵션이었다. 2001년 초, 암호학자들이 몇 가지 치명적인 취약점을 발견하였으며, 이를 이용하면 누구나 구할 수 있는 소프트웨어를 사용해 몇 십 분만에 WEP 연결을 크랙할 수 있다. 출처: 위키백과 https://ko.wikipedia.org/wiki/%EC%9C%A0%EC%84%A0_%EB%8F%99%EB%93%B1_%ED%94%84%EB%9D%BC%EC%9D%B4%EB%B2%84%EC%8B%9C |
IEEE 802.11i 표준이 출시될 때 까지 취약한 WEP[3]을 대신하기 위해 2002년에 발표한 암호화 규격. TKIP라는 암호화 프로토콜도 새로 개발되었는데, 당시에 WEP는 64, 128비트로 패킷을 암호화 하지만, 한번 만들어지면 절대 바뀌지 않는 암호화 키 때문에 보안이 쉽게 뚫렸다. WPA는 이러한 단점을 보완해서 한 패킷에 한번씩 지속적으로 암호화를 해서 보안을 더 철저히 한다. 2004년에 발표한 새로운 암호화 규격. IEEE 802.11i-2004 표준을 기반으로 한다. 취약한 WEP을 대체하기 위해 개발되었다. AES-CCMP128 암호화 프로토콜을 사용하며, TKIP는 암호화 방식에서 제외되었다. 또한, WPA2에서는 암호가 일정 길이 이상이 되어야 한다. 출처: 나무위키 https://namu.wiki/w/WPA |
String형식으로 반환되는데
"WEP"형식일 경우 이를 알려주기!
NetworkType
private val connectivityManager: ConnectivityManager =
context.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
다음은 셀룰러 데이터인지 확인하는 함수 그냥 간단한데
fun checkNetworkType(): String {
val network = connectivityManager.activeNetwork
val networkCapabilities = connectivityManager.getNetworkCapabilities(network)
return when {
networkCapabilities == null -> "NONE" // 네트워크가 연결되지 않음
networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> "WIFI"
networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> "CELLULAR"
networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> "ETHERNET"
else -> "OTHER"
}
}
NetworkCapabilities.TRANSPORT_WIFI, TRANSPORT_CELLULAR, TRANSPORT_ETHERNET
을 통해서 반환되는 String을 체크하면 됨 !
반응형