안드로이드 스투디오에서 keystore 정보 관리하기

지난 글에서 debug 용 키스토어(alias, key password, store password가  기본 값)를 만드는 법을 안내했었다.

안드로이드 스투디오에서는 두가지 프로젝트를 읽을 수 있다. 그 중에 안드로이드 스투디오에서 권장하는 Gradle-based project를 만들면,  signing할 때 사용할 key 정보를 관리할 수 있다.

이전까지 Intelli J나 Eclipse에서는 apk를 단말에서 실행하면서 동시에 signing을 자동으로 할 방법이 debug용 키스토어를 만드는 것 뿐이었다. 하지만, 위를 기능을 이용하면 릴리즈용 키 정보도 입력해 두었다가 자동으로 signing을 할 수 있다.

물론 여전히 디버그용 키스토어는 password나 alias를 노출하지 않는 면에서 의미가 있다.

File > Project Structure > Signing 탭을 통해 여러개의 key를 미리 등록해둘 수 있다.

 

signingkey

참고로, password를 잊어버리면 앱을 signing할 수 없었던 문제 때문이었는지, key password와 store password 부분이 plain text로 표시되도록 바뀌었다.

대신에 store password를 제대로 입력하면 key alias를 자동으로 표시해주었던 Eclipse와 달리 alias도 직접 입력해야한다. 만약 alias가 기억 나지 않는다면, JDK에 내장된 keytool을 통해 확인할 수 있다.

keytool -list -keystore [keystore 파일 이름]

참고

  • http://stackoverflow.com/questions/12893995/how-to-check-certificate-name-and-alias-in-keystore-files

키스토어에서 해시코드 추출하기

페이스북의 기능(SSO 등)을 사용할 경우 앱의 키스토어에서 아래와 같은 방법을 통해 해시코드를 만들어서 사용자의 페이지에 등록하도록 요청한다.

keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore | openssl sha1 -binary | openssl base64

이 방법은 리눅스/맥을 기반으로 작성된 예제인데, 만약 윈도우에서 안된다면 아래와 같이 써보자.

keytool -export -alias androiddebugkey -keystore ~/.android/debug.keystore | openssl sha1 -binary | openssl enc -a -e

위와 같은 복잡한 해시코드 대신에 간단한것을 원한다면, 자바의 String 클래스의 hashcode()를 이용해도 된다. 이 함수는 32bit 해시코드를 반환하는 것으로 원래 자바 내부적으로 사용할 목적으로 추가된 메소드이다.

마지막으로, 다른 값을 이용해 만든 해시코드가 같을 수 있다는 사실을 잊고, 유니크 키를 대신한다던가 하는 실수를 하지 말자.  예로 “Z@S.ME”와 “Z@RN.E”의 String.hashcode() 값은  아래와 같다.

========================
"Z@S.ME".hashcode();
"Z@RN.E".hashcode();
========================
Z@S.ME = -1656719047
Z@RN.E = -1656719047

참조

  • http://stackoverflow.com/questions/12626253/keytool-gives-wrong-android-apk-hashcode
  • http://stackoverflow.com/questions/4388992/key-hash-for-android-facebook-app
  • http://stackoverflow.com/questions/6120657/how-to-generate-a-unique-hash-code-for-string-input-in-android
  • http://en.wikipedia.org/wiki/Java_hashCode()

사인한 키스토어(keystore) 확인하기

안드로이드 어플리케이션은 .keystore 파일을 이용해 내 앱을 사인(signing)할 수 있다. 앱이나 키스토어(keystore)가 한두개라면 모르겠지만, 각 앱마다 다른 키스토어를 만들었다거나 테스트용, 릴리즈용 등으로 여러개의 앱을 가지고 있다보면 사인이 되긴 된건지, 어떤 키로 사인이 된건지 헷갈린다. (CI 환경을 만들어서 차곡차곡 정리해두면 헷갈리 없겠지만)

사인이 된 앱을 가지고 있고, 이 앱이 어떤 키스토어로 사인이 되었는지 확인하고 싶다면 어떻게 해야할까? 결론부터 이야기하면, 앱과 키스토어의 Certificate fingerprint를 비교하면 된다.

먼저 키스토어에서 fingerprint를 확인해보자.

>keytool -list -keystore my-keystore.keystore
Enter keystore password:

키스토어의 비밀번호를 입력하면 다음과 같이 키스토어에 포함된 alias 들의 정보가 출력된다.

Keystore type: JKS 
Keystore provider: SUN 

Your keystore contains 1 entry 

my-service, 2016. 10. 19, PrivateKeyEntry, 
Certificate fingerprint (SHA1): 3C:B6:68:E2:8A:EC:9F:16:7E:2C:20:AA:B2:71:12:1B:98:F2:1E:D9

출력된 데이터에서 Certificate fingerprint 부분을 확인한다.

이번에는 사인된 앱에서 Certificate fingerprint를 확인해보자. 키스토어를 확인할 때와 마찬가지로 keytool을 이용한다.

>keytool -list -printcert -jarfile my-app.apk

위와 같이 커맨드라인에서 입력하면, 앱 안의 META-INF 폴더 안의 .RSA 파일에서 인증서 정보를 추출하여 인증서의 정보를 보여준다.

...
Certificate fingerprints:
MD5: D8:2A:99:53:1E:7E:9D:B5:3A:44:FC:2D:99:48:38:17
SHA1: 3C:B6:68:E2:8A:EC:9F:16:7E:2C:20:AA:B2:71:12:1B:98:F2:1E:D9
SHA256: 5E:9C:8E:B8:D0:8E:E7:44:7B:5D:B5:1D:83:1F:D3:80:84:0C:F2:DC:15:DC:71:1E:E6:20:70:D6:B4:7B:9C:AB
...

그 중에서 같은 방법으로 만들어진 Certificate fingerprint를 비교해서 같다면, 이 앱은 이 키스토어로 사인된 것으로 보면 된다.

그리고 위에서 언급했듯이 인증서의 위치가 META-INF/*.RSA로 고정되어 있다. 그러므로, .apk 파일을 압축해제 한 후에 META-INF/*.RSA 파일에 아래 명령어를 실행해도 Certificate fingerprint를 꺼낼 수 있다.

keytool -printcert -file CERT.RSA

참조

INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES

이미 같은 package name을 가진 apk가 있는데, 설치된 apk와 설치할 apk의 keystore가 다르다는 내용이다.

이유는 두가지인데,

  • 다른 앱인데 같은 패키지 이름을 가진 경우
  • 같은 앱인데 다른 keystore(예. IDE의 default keystore와 릴리즈용 keystore)를 사용한 경우

이다. 이 때는 이전의 apk를 삭제하거나 같은 keystore로 다시 signing한 후에 설치를 시도해야 한다.

참고로, adb install 명령어의 어떤 옵션으로도 덮어씌우기는 할 수 없다. 아마도 패키지 이름과 keystore가 맞지 않는다면 다른 소유주로 판단하는 것 같다. 그 근거는 자바 언어의 권장에 따라,

  • package name에는 도메인을 거꾸로한 이름을 쓰게되어있어 같기가 거의 불가능하고,
  • keystore는 만들 때마다 새로 만들어지기 때문에 이론상 같을 수 없기 때문이다.

그래서 실수로 이미 공개된 앱의 keystore를 분실하면, 매우 곤란한 문제에 부딪히곤 한다.

인텔리제이에서 키스토어(Keystore) 위치 지정하기

일반적인 경우, 키스토어(Keystore)는 Android Studio나 Intelli J같은 IDE에서 관리를 해준다. 취미로 개발하는 경우에는 기본으로 내장된 키스토어를 사용하면 되고, 신규로 키스토어를 만드는 경우에도 마법사 기능을 통해 잘 지원한다.

그런데, 여러개의 앱을 같은 키스토어를 이용해 사인(signing)한 후에 자원(resource)를 공유한다던가, 기존에 만들어진 키스토어를 새로 셋팅된 IDE에 넣고 싶다면 어떻게해야할까? 키스토어를 지정해주어야한다.

인텔리제이 12를 기준으로 설명하면,

  • 실제로 앱을 마켓에 올리기 위해 만드는 경우에는 “File | Project Structure | Artifacts”에서 새 Artifact를 추가해 키스토어 위치를 지정해주면 된다.
  • 디버깅용 키스토어도 만들어서 사용하고 있다면 이는 “File | Project Struecture | Facets”에서 키스토어를 바꿀 Android 프로젝트를 선택한 후에 Compiler 탭에서 위치를 지정하면 된다.

참고 : http://stackoverflow.com/questions/5860399/using-custom-debug-keys-in-intellij-idea-10-community-ed