본문 바로가기

만났던 에러들

카카오네비게이션 KNError(code=C103, msg=SDK Certification Failed - INVALID_TOKEN, tagMsg=null, extra=null) 에러

과정을 다 보고 싶은 사람은 정독을 하면 되지만, 굳이 그런게 아니라면 그냥 ctrl+F 를 누르고 "여기서 부터" 를 입력후 해당 부분부터 블로그의 글을 보세요.

 

에러구문에서 이미 무엇이 잘못되어 있는지 확인할 수 있다.

토큰값이 잘못됐다는 말인데 이는 카카오 developer 사이트에 키 해시값을 잘못 설정했다는 말이다.

개발하는 pc마다 다 따로 키 해시값을 뽑아내서 등록해줘야 하고 윈도우냐 맥이냐에 따라 방법도 다르다.

 

맥의 경우는 key hash의 값을 뽑아내는게 엄청 쉬웠다. 하지만 안드로이드의 경우는 조금 더 복잡했다.

우선 안드로이드의 terminal 창을 열고 open ssl 명령어를 입력해야 하지만 따로 설치를 하지 않았다면 에러를 만나게 된다.

 

" 'openssl’은 내부 또는 외부 명령, 실행할 수 있는 프로그램, 또는 배치 파일이 아닙니다 ... "

 

openssl은 검색하면 쉽게 다운받을 수 있다. chatGpt에게 물어보면 이것도 수동 설치법과 Chocolatey 패키지 관리자 사용법을 활용해서 설치하는 방법 두개를 알려준다.

 

(자세한건 직접 물어봐도 될 것 같습니다.)

 

(open ssl을 설치하고 환경변수에 등록해줘야 합니다. 이또한 많은 블로그에 설명하고 있기 때문에 굳이 적지 않겠습니다.)

등록을 마치고 안드로이드스튜디오의 termianl 창에서 아래와 같은 명령어를 자신의 경로에 맞춰 입력해주면 된다.

keytool -exportcert -alias androiddebugkey -keystore %USERPROFILE%\.android\debug.keystore -storepass android -keypass android | openssl sha1 -binary | openssl base64

 

저기서 %USERPROFILE% 이라고 들어가는 부분은 설정된 본인의 pc경로를 넣어주면 된다. 예를 들어서 내 debug.keystore 파일이 아래 경로에 있다고 가정해보자.

C:\Users\asus vivo\.android

 

그럼 아래와 같이 문장이 완성될 것이다. 

keytool -exportcert -alias androiddebugkey -keystore C:\Users\asus vivo\.android\debug.keystore -storepass android -keypass android | openssl sha1 -binary | openssl base64

 

하지만.. asus vivo 라는 이름은 중간에 띄워쓰기가 포함되어있다. 

이를 해결하려면 또 띄워쓰기를 무시하기위한 문자열 설정을 명령어에 입력해줘야 하는데 너무 귀찮았다.

 

여기서 부터

 

그냥 아래 코드를 자신의 앱이 가장 처음 시작하는 activity에 넣어두고 log로 확인하면 된다.

그럼 키 해시값을 쉽게 확인할 수 있다. getKeyHash() 메소드에서 로그로 확인하면 될 일이다.

 

class MainActivity : AppCompatActivity(), View.OnClickListener {

    lateinit var btnGuide: Button
    val TAG : String = "MainActivity";
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)


        getKeyHash()

        btnGuide = findViewById(R.id.btn_guide)
        btnGuide.setOnClickListener(this)
    }

    fun getKeyHash() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            val packageInfo = this.packageManager.getPackageInfo(this.packageName, PackageManager.GET_SIGNING_CERTIFICATES)
            for (signature in packageInfo.signingInfo.apkContentsSigners) {
                try {
                    val md = MessageDigest.getInstance("SHA")
                    md.update(signature.toByteArray())
                    //로그를 찍을때 편리한 라이브러리인 Logger를 사용했습니다. 따로 공부해보시고 주석을 풀어서 써보시는 것을 추천드립니다.
                    //Logger.v("key hash: ${Base64.encodeToString(md.digest(), Base64.NO_WRAP)}")
                    Log.v(TAG, "key hash: ${Base64.encodeToString(md.digest(), Base64.NO_WRAP)}")
                } catch (e: NoSuchAlgorithmException) {
                    //Logger.v("Unable to get MessageDigest. signature=$signature", e)
                }
            }
        }
    }
    
    ...
    
}

 

게시글을 작성하면서 참고한 블로그

https://manorgass.tistory.com/76

(키 해시에 관한 개념을 자세하고 쉽게 잘 설명해주셨다.)