IT_Programming/Android_Java

[펌] 구글 플레이 앱 서명 시 알아야 할 몇 가지

JJun ™ 2017. 12. 27. 22:01



 출처

 : https://medium.com/@jungil.han/구글-플레이-앱-서명-시-알아야-할-몇-가지-ac86952889bf










구글 플레이 콘솔의 새로운 기능인 구글 플레이 앱 서명(Google Play App Signing) 기능을 사용하기 전에 알았으면 좋았을 내용을 정리해보았습니다. 이미 구글 플레이 스토어에 배포된 앱에 해당 기능을 활성화할 예정이라면 이로 인한 영향에 대해 좀 더 면밀히 살펴볼 필요가 있겠습니다. 이 기능은 한번 활성화하면 되돌릴 수 없습니다.

앱 서명 키와 업로드 키

개발자가 APK 배포 시 앱 서명을 하던 기존 방식과 달리 구글 플레이 앱 서명은 업로드 키로 서명된 APK를 구글 플레이에 업로드하면 구글이 업로드 인증서를 확인 후 앱 서명 키로 재서명을 합니다. 업로드 서명은 이름 그대로 업로드 시 검증을 위해서만 사용되며 앱 서명 키로 서명되기 전 삭제됩니다. 이제 개발자는 로컬에 앱 서명 키가 아닌 업로드 키를 보관하면 되고, 앱 서명 키는 구글의 인프라를 통해 관리되므로 앱 서명 키를 분실하는 문제로부터 자유로워질 수 있습니다. 다만 마음의 준비가 필요한 부분이라면 개발자가 배포용으로 빌드 한 APK와 구글 플레이에 배포한 APK의 서명이 다름으로 발생하는 일련의 현상들입니다.

릴리스 키 해시

페이스북, 카카오와 같은 앱 서명 키에서 구한 키 해시를 요구하는 SDK는 업로드 서명 키와 앱 서명 키에서 얻은 키 해시를 모두 등록해야 합니다. 업로드 서명 키는 대개 로컬 PC에서 관리하니 keytool을 이용해 키 해시를 얻을 수 있지만 앱 서명 키는 구글이 관리하기 때문에 이 방식으로 키 해시를 얻을 수 없습니다. 다음 화면처럼 구글 플레이 콘솔의 “출시 관리 > 앱 서명” 메뉴를 통해서 앱 서명 인증서를 확인할 수 있습니다.



예로 페이스북 SDK는 SHA-1 지문에서 생성된 해시를 필요로 하는데 위에서 얻은 값을 이용해 다음과 같이 구할 수 있습니다.

#] echo 11:22:33:44:55:66:77:88:99:00:AA:BB:CC:DD:EE:FF:A0:B1:C2:D4 | xxd -r -p | openssl base64

매번 구글 플레이 콘솔에서 확인하는 것이 번거롭다면 오른쪽 상단의 인증서 다운로드 버튼으로 인증서를 내려받아 다음과 같이 정보를 확인하는 것도 방법입니다.

#] keytool -printcert -file ./deployment_cert.der


INSTALL_FAILED_UPDATE_INCOMPATIBLE 에러

플레이 스토어에서 내려받은 APK가 설치된 폰에 곧 출시될 새로운 프로덕션 APK를 올리는 테스트 상황을 가정해봅시다. gradlew assembleProductionRelease로 배포 예정인 APK를 생성한 후 adb install -r xxxx-1.0.4–11-production-release.apk로 설치하면 성공적으로 업데이트가 돼야 하지만 구글 플레이 앱 서명이 활성화되어 있다면 다음과 같은 에러가 발생합니다.

[INSTALL_FAILED_UPDATE_INCOMPATIBLE: Package xx.xxxxxxxxxx.xxxxxxx signatures do not match the previously installed version; ignoring!]

플레이 스토어에 배포된 APK와 개발자가 빌드 한 APK의 인증서 서명이 맞지 않아 설치가 실패합니다. 이는 구글 플레이 앱 서명이 업로드 키로 서명된 APK를 앱 서명 키로 다시 서명하는 과정에 의해 발생하는 현상입니다. 즉, 개발자가 빌드 한 APK는 업로드 키로 서명이 된 상태이고, 플레이 스토어로 배포된 APK는 앱 서명 키로 서명이 됐기 때문입니다. 만일 앱 서명 키로 서명된 APK를 생성하지 못하면 adb install로 앱을 업데이트를 할 수 없는 상황이 발생할 수 있는데 다행히 앱 서명 키로 서명된 APK는 구글 플레이 콘솔에서 내려받을 수 있습니다. “출시 관리 > 앱 버전 > 프로덕션 버전 관리”의 업로드된 APK 메뉴의 다운로드 버튼을 클릭하면 다음과 같은 화면이 나옵니다.


기존 APK라고 쓰인 것이 업로드 키로 서명된 APK이고, 파생된 APK가 앱 서명 키로 서명된, 실제 플레이 스토어를 통해 사용자에게 배포되는 APK입니다. 파생된 APK를 내려받아 adb install로 업데이트를 실행해야 성공적으로 설치됩니다. 눈치 채셨겠지만 구글 플레이 콘솔에 APK를 업로드 해야지만 앱 서명 키로 서명된 APK를 얻을 수 있는 불편함이 있습니다.


다중 APK와 최적화

구글은 앱 서명 키로 재서명을 하기 전에 밀도, 아키텍처 별로 APK 최적화를 수행합니다. 예를 들면 xhdpi 디바이스를 위해 xhdpi 이외의 폴더를 제거한다거나 x86 디바이스를 위해 다른 아키텍처용 네이티브 라이브러리를 제거하는 방식으로 APK 파일 사이즈를 최소화합니다. 기존에는 개발자가 직접 다중 APK를 생성하고 플레이 스토어에 업로드해야 했지만 이제는 유니버셜 APK를 업로드하면 구글이 이 작업을 직접 처리합니다. 이는 구글이 APK 서명에 관여하게 되면서 얻게된 이점입니다. 위 동영상에 자세한 내용이 담겨 있습니다.


맺으며

새로운 앱을 출시하면서 INSTALL_FAILED_UPDATE_INCOMPATIBLE 에러를 맞닥들이고 (그 당혹스러움과 불안함이란) 한참을 ‘뭐가 문제일까?’를 살폈습니다. 기억이 가물가물할 정도의 시간 이전에 활성화해 둔 구글 플레이 앱 사이닝이 떠올라 그제서야 관련 자료를 다시 살펴보고 원인을 알게 됐습니다. 기존의 앱 서명 키가 업로드 키로 바뀌었을 뿐 체감 변화가 없다는 점이 문제 발견을 느리게 하는데 한몫했을지도 모르겠습니다. 한편으로는 물 흐르듯 자연스럽게 해당 기능을 사용할 수 있다는 의미일 수도 있습니다. 부수효과인 다중 APK와 최적화가 매력적이지만 해당 기능을 사용하기 전 배포 루틴의 변화가 프로젝트에 미치는 영향이 어느 정도인지 미리 가늠해보시길 권장합니다.