일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 통신3사
- 공공임대
- 국임
- AOFO Smart power
- 장전
- sh공사
- 시놀로지
- 행복주택
- KT
- 2018 공급계획
- LG
- AI 카메라
- 퇴직한 직장인
- 공공분양
- 워렌버핏
- 펜타카메라
- 강환국
- 국립항공박물관
- 일반근로자
- 2017년 분양계획
- 국민임대
- 평강랜드
- 스마트 멀티탭
- SH
- 3자녀우선
- 분양
- 소득조회
- 가치투자
- 알뜰폰
- 장기전세
- Today
- Total
초코비니
[Tip] 어플리케이션 서명(signing) 및 배포, 그리고 debug용 keystore 만들기 본문
Android App을 만든 후 apk를 생성하여 배포할 때, apk에는 반드시 서명 작업(signing)이 되어 있어야한다. 그렇지 않으면 해당 apk는 절대로 단말기에 설치 할 수 없다. apk를 생성하면서 서명하는 방법에 대해 알아보자.
배포용 APK 만들기
Android Studio에서 프로젝트를 apk로 생성하려면 상단 메뉴의 'Build - Generate Signed APK ...'를 선택하면 된다. 그러면 아래와 같은 팝업이 뜰텐데, 대충 내용은 Gradle 기반의 프로젝트는 gradle build script에서 signing 관련 정보를 정의해라, 그리고 'gradle assembleRelease'를 실행하면 build/apk 디렉토리에 APK가 생성될 것이다라는 내용이다. 본 포스트에서는 배포용 APK를 만드는 여러 방법에 대해 설명 할 것이므로 일단 OK 버튼을 눌러 다음 화면으로 이동하자.
1. Android Studio의 기능을 이용해서 배포
일단 gradle build script 말고 Android Studio에서 지원하는 방법을 사용해보자. OK 버튼을 누르면 다음과 같이 프로젝트를 선택하는 팝업이 나오는데, APK로 만들 프로젝트를 선택한 후 Next를 누른다.
그러면 또 아래와 같이 keystore에 대한 정보를 입력하라고 나오는데, 만들어 둔 keystore가 있다면 해당 keystore를 사용하면 될 것이고, 없다면 Create new... 를 선택한다.
keystore란? (출처 : 커니의 안드로이드 이야기) 어플리케이션 서명을 위해 사용하는 수단으로, 자신의 '서명'이라 할 수 있다. 서명은 'key'로 하게 되며, keystore는 서명을 할 수 있는 key들을 담을 수 있는 파일을 뜻한다. IDE를 통한 개발시 기본으로 디버그용 키를 사용하여 어플리케이션 패키지를 서명하게 되며, Google play store 등 외부로 어플리케이션을 배포할 때는 자신의 키를 사용하여 배포해야 한다. (배포 후 키를 잃어버리면 업데이트가 불가능하다!) 왜 서명이 필요한가? 악의적인 목적으로 리패키징 된 apk를 구분하기 위해서다. 어플리케이션을 배포할 때 apk로 패키징하게 되는데 이 때, 누가 패키징 했는지 정보를 기록하는게 서명 작업이다. signing에 대한 참고 자료 http://developer.android.com/tools/publishing/app-signing.html |
아래와 같이 필요한 정보들을 입력해준다. (Certificate 항목은 필수가 아니다. 그리고 Validity는 유효기간을 의미하므로 넉넉하게 넣어주자. 너무 큰 숫자를 넣으면 keystore가 정상적으로 생성되어도 hashcode of signature는 invalid하더라)
필요한 정보들을 입력한 후 OK 버튼을 누르면 아래와 같이 폼들이 자동으로 채워지게 된다. Next를 눌러 이동하자.
마스터 패스워드를 지정하라고 한다. 귀찮으니 keystore와 동일한 암호로 지정한다.
생성될 APK 파일의 경로를 지정하고 Proguard를 적용 할 것인지 선택 후 Finish 버튼을 누르면 APK가 생성 될 것이다.
Keystore를 만드는 또다른 방법, keytool을 이용해 keystore를 생성해보자. 사실 이게 오리지널이다. JDK에 포함된 keytool을 이용하면 터미널에서 keystore를 생성할 수 있다. 터미널에서 아래와 같이 입력한다.
그러면 아래와 같이 Android Studio와 동일한 순서로 정보를 입력 하게 되며, 마지막엔 *.keystore를 생성해 준다. 잠깐, *.keystore와 *.jks의 차이는? Android Studio에서 생성한 keystore는 *.jks 확장자를 가질 것이며, 터미널에서 keytool을 이용해 직접 만든 keystore는 *.keystore 확장자를 가지는데 사실 이는 확장자만 다르지 똑같은 keystore 파일이다.(터미널에서 생성할 때 *.jks 확장자로 지정해 주면 그냥 생성된다.) jks는 Java security provider에서 제공하는 keystore의 default type을 의미한다. (자세한 내용은 여길 참고하라) |
* 해당 어플리케이션이 정상적으로 서명이 되었는지 확인하는 방법.
이건 그냥 참고로 알아두면 좋은데, 잘못 만들어진 keystore로 서명할 경우 signature의 hashcode가 음수로 나오는 경우가 있다.(유효기간을 50년이상으로 하니까 hashcode가 이상하게 나오더라...) 정상적이라면 아래와 같이 나와야 한다.
1 | 04-29 10:58:36.387 11231-11231/com.jhlee.myapplication.app D/myapp﹕ Signature hashcode : 826338355 |
signature에 대한 hashcode를 얻는 코드.
1 2 3 4 5 6 7 8 9 10 11 12 13 | import android.content.pm.PackageManager; import android.content.pm.Signature; ... try { Signature[] sigs = this .getPackageManager().getPackageInfo(getPackageName(), PackageManager.GET_SIGNATURES).signatures; for (Signature sig : sigs) { Log.d( "myapp" , "Signature hashcode : " + sig.hashCode()); } } catch (Exception e) { Log.d( "myapp" , e.getMessage()); } |
2. Gradle Build Script를 이용해서 배포.
Android Studio에서 APK를 생성할 때 처음 팝업 화면에 아래와 같이 안내문이 있었다.
For Gradle-based projects, the signing configuration should be specified in the Gradle build scripts. Configure your signing configurations as described in the user guide: http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Signing-Configurations Then, run "gradle assembleRelease", and you will find your APK in the build/apk/ directory. |
gradle build script에 keystore을 지정해주고 'gradle assembleRelease'를 실행하면 APK가 생성된다는 말이다.
APK를 생성할 프로젝트의 build.gradle을 아래와 같이 편집하자.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | android { compileSdkVersion 19 buildToolsVersion "19.0.3" defaultConfig { minSdkVersion 8 targetSdkVersion 19 versionCode 1 versionName "1.0" } // 요기랑 signingConfigs { release { storeFile file( "signature/release.jks" ) storePassword "123456" keyAlias "myreleasekey" keyPassword "123456" } } buildTypes { release { signingConfig signingConfigs.release // 여기 debuggable false // debugging 허용 안함 zipAlign true // apk 최적화 runProguard false proguardFiles getDefaultProguardFile( 'proguard-android.txt' ), 'proguard-rules.txt' } } } |
해당 task를 실행하면 build.gradle로부터 signing 정보를 확인하게 되므로 따로 윈도우를 통해 keystore를 지정해 주지 않아도 된다.
task가 종료되면 프로젝트\build\apk 디렉토리가 생성될 것이며 아래와 같이 두 개의 apk가 만들어질 것이다. 두 가지의 차이점은 unaligned-apk는 최적화되지 않은 APK이고 이 APK를 바탕으로 zipAlign 작업을 수행하여 app-release.apk가 생성되는 것이다. 그러므로 app-release.apk만 배포하면 된다.
3. Release한 App을 디버깅해보자.(debug용 keystore 만들기)
자 이제 App을 배포했고 수정할 사항이 생겨서 App이 설치된 단말기에서 디버깅을 하려 한다. 그러나 아마 아래와 같은 오류가 뜰 것이다.
콘솔 에러를 보면 아래와 같다.
Waiting for device. Target device: samsung-sm_g900k-92b54d52 Uploading file local path: /Users/jhlee/Documents/Workspace/AndroidStudio/MyApplication/app/build/apk/app-debug-unaligned.apk remote path: /data/local/tmp/com.jhlee.myapplication.app Installing com.jhlee.myapplication.app DEVICE SHELL COMMAND: pm install -r "/data/local/tmp/com.jhlee.myapplication.app" pkg: /data/local/tmp/com.jhlee.myapplication.app Failure [INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES] |
에러가 발생하는 이유는 간단하다. 디버깅을 위해 만들어진 app-debug-unaligned.apk의 signing 정보와 이미 단말기에 배포된 app-release.apk 정보가 다르기 때문이다. signing을 하는 이유는 위에서 설명했듯이 이런식으로 다른 인증을 통해 리패키징 된 어플리케이션을 구분하기 위해 사용하며, 이런 에러가 발생하는 것은 당연하다. 물론 해결책은 있다. 팝업 메세지처럼 이미 배포된(설치된) 앱을 지우고 디버깅을 시작하면 된다. 그러나 귀찮다. 그리고 우린 개발자다. 뭔가 다른 방법이 없을까.
방법은 간단하다. release용 keystore로부터 debug용 keystore를 만들어서 build.gradle에 지정 해주면 된다. debug용 keystore는 아래와 같이 keytool을 이용해 생성 할 수 있다.
(명령어 출처 : http://sunphiz.me/wp/archives/114)
1 | keytool -importkeystore -v -srckeystore [릴리즈용 키스토어 파일이름] -destkeystore [디버그용 키스토어 파일이름] -srcstorepass [릴리즈용 키스토어 비밀번호] -deststorepass android -srcalias [alias 이름] -destalias androiddebugkey -srckeypass [alias 비밀번호] -destkeypass android |
debug용 keystore의 비밀번호와 alias는 고정이어야 하는가? 위 명령어를 살펴보면 debug용 비밀번호는 android, alias는 androiddebugkey로 지정되어 있는데, 사실 이클립스나 Android Studio에서 디버그를 할 때 자동으로 서명되는 keystore의 비밀번호와 alias랑 동일한 것이다. 왜 동일하게 했냐면 build.gradle에서 debug용 keystore 지정시, 비밀번호와 alias를 지정해주지 않으면 IDE는 자동으로 위 비밀번호와 alias를 사용하기 때문이다. (편의상 동일하게 사용 하는 것으로 이해하면 된다.) IDE에서 자동으로 서명하는 keystore의 파일 위치 Eclipse의 경우 Preferences -> Android -> build에서 default debug keystore의 경로를 확인 할 수 있다. |
이제 build.gradle을 편집하자. 아래와 같이 debug일 경우에 사용 할 keystore 파일과 builTypes.debug시 사용 할 서명 방식을 지정해준다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | signingConfigs { debug { storeFile file( "signatrue/debug.jks" ) // storePassword "android" // keyAlias "androiddebugkey" // keyPassword "android" } release { storeFile file( "signature/release.jks" ) storePassword "123456" keyAlias "myreleasekey" keyPassword "123456" } } buildTypes { debug { signingConfig signingConfigs.debug } release { signingConfig signingConfigs.release runProguard false proguardFiles getDefaultProguardFile( 'proguard-android.txt' ), 'proguard-rules.txt' zipAlign true debuggable false } } |
Waiting for device. Target device: samsung-sm_g900k-92b54d52 Uploading file local path: /Users/jhlee/Documents/Workspace/AndroidStudio/MyApplication/app/build/apk/app-debug-unaligned.apk remote path: /data/local/tmp/com.jhlee.myapplication.app Installing com.jhlee.myapplication.app DEVICE SHELL COMMAND: pm install -r "/data/local/tmp/com.jhlee.myapplication.app" pkg: /data/local/tmp/com.jhlee.myapplication.app Success |
'안드로이드' 카테고리의 다른 글
안드로이드 앱 버전 확인하기. (0) | 2015.11.29 |
---|---|
View 객체 내가 원하는 부분만 제거 하고 싶을때... (0) | 2015.10.25 |
안드로이드(Android) 원본 리소스 raw (0) | 2015.09.16 |
안드로이드 MultiDex 지원 (0) | 2015.09.08 |
안드로이드 스튜디오 기준(gradle build) v4 충돌 (0) | 2015.09.03 |