이전 포스팅이 존재합니다.
1편 : https://nemomemo.tistory.com/187
2편 : https://nemomemo.tistory.com/188
이 블로거의 혼란을 야기하므로 용어는 영어로 사용하고자 합니다.
빌드 변형 = build variant
빌드 유형 = build types
제품 버전 = product flavors
버전 차원 = flavor dimension
소스 세트 = source sets
서명 구성 = signing configuration = signing settings
키 저장소 = keystore
private key = 비공개 키
종속 = dependencies
서명 = signing
API 수준 = API level
signing configuration (서명 구성)
- (얘도 정말 의미 그래로) 안드로이드 서명(signing)에 대해 build 파일에 설정
- 왜 필요한가?
signing configuration을 생성하고 'release' build types에 할당하면 앱의 'release' 버전에 빌드 시 자동으로 서명하도록 프로젝트를 구성할 수 있다.
- Android에서는 인증서를 사용해 디지털 방식으로 서명된 APK만 기기에 설치하거나 업데이트할 수 있다.
- keystore 위치, keystore password, key alias, and key password로 구성
['release' build types의 signing configuration을 직접 설정하기]
- 'keystore'를 생성합니다.
- keystore : private key(비공개 키) 세트가 포함된 바이너리 파일
- keystore는 안전하고 보안이 유지되는 장소에 보관해야 한다. - 'private key'를 생성합니다.
- 'private key'는 배포를 위해 앱에 서명하는 데 사용되는 키. (앱에 포함되거나 승인되지 않은 서드 파티에 공개되지 않음) - signingConfigs { create("release") { ... } } 블록 내에 1, 2번에 관한 signing 정보를
앱 단(모듈 수준) build.gradle 파일에 추가한다.
...
android {
...
defaultConfig {...}
signingConfigs {
create("release") {
storeFile = file("myreleasekey.keystore")
storePassword = "password"
keyAlias = "MyReleaseKey"
keyPassword = "password"
}
}
buildTypes {
getByName("release") {
...
signingConfig = signingConfigs.getByName("release")
}
}
}
위의 방법이 기본적인 방법이나
keystore 정보가 빌드 파일에 저렇게 문자열로 노출된 채 있는 것은
보안상 매우 안 좋다
따라서
[빌드 파일에서 signing configuration 삭제]
대안 1. (조금 나은)
환경 변수에서 데이터를 가져도록 build 파일을 구성
storePassword = System.getenv("KSTOREPWD")
keyPassword = System.getenv("KEYPWD")
대안 2. (더 나은)
1) signing configuration을 생성한 후 하나 이상의 build types에 할당합니다. ex) 'release'
1-#1) 스튜디오에서 지원하는 Project > Open Module Settings 창에서 설정
1-#2) 앱 모듈 단 build.gradle.kts에 아래 코드처럼 직접 작성
@ project/app/build.gradle.kts
signingConfigs {
create("release") {
다른 위치에 keystore.properties 파일을 저장
- 사용CASE) 프로젝트의 루트 폴더 대신 모듈 폴더에 저장하거나 지속적 통합 도구를 사용하는 경우 빌드 서버에 저장할 수 있다.
- 사용법) 이 경우 실제 keystore.properties 파일의 위치를 사용하여 keystorePropertiesFile을 올바르게 초기화하도록 위 코드를 수정해야 함
2) 프로젝트의 루트 디렉터리에 keystore.properties라는 이름의 파일을 생성하고, 아래와 같이 signing configuration정보를 기재
- keystore.properties 파일을 안전하게 보호해야 한다.
@ project/keystore.properties
storePassword=myStorePassword
keyPassword=mykeyPassword
keyAlias=myKeyAlias
storeFile=myStoreFileLocation
3) 앱 모듈 단 build.gradle 파일에서 keystore.properties 파일을 로드하는 코드를 android {} 블록 앞에 추가
@ project/app/build.gradle.kts
...
import java.util.Properties
import java.io.FileInputStream
val keystorePropertiesFile = rootProject.file("keystore.properties")
val keystoreProperties = Properties()
keystoreProperties.load(FileInputStream(keystorePropertiesFile))
android {
...
}
// keystorePropertiesFile변수를 만들고 rootProject 폴더에 있는 keystore.properties 파일로 초기화한다. val keystorePropertiesFile = rootProject.file("keystore.properties") // keystoreProperties변수를 만들고 Properties()객체를 생성해 할당 val keystoreProperties = Properties() // keystore.properties 파일을 keystoreProperties 객체로 로드 keystoreProperties.load(FileInputStream(keystorePropertiesFile)) |
4) keystoreProperties['propertyName'] 구문을 사용하여 keystore.properties파일의 signing configuration 정보를 앱 모듈 단 build.gradle 파일의 signingConfigs{} 블록 내 기재
- keystoreProperties['propertyName'] 구문 : keystoreProperties에 저장된 속성을 참조가능하다.
@ project/app/build.gradle.kts
android {
signingConfigs {
create("config") {
keyAlias = keystoreProperties["keyAlias"] as String
keyPassword = keystoreProperties["keyPassword"] as String
storeFile = file(keystoreProperties["storeFile"] as String)
storePassword = keystoreProperties["storePassword"] as String
}
}
...
}
5) Build Variants 도구 창을 열고 출시 빌드 유형이 선택되었는지 확인
6) Build > Build Bundle(s) / APK(s) 옵션 선택 > 'release' 빌드의 APK 또는 App Bundle을 빌드
- 빌드 출력은 모듈의 build/outputs/ 디렉터리에서 확인할 수 있습니다.
이제 빌드 파일에 더 이상 민감한 정보가 포함되어 있지 않으므로
빌드 파일을 소스 제어에 포함하거나 공유 코드베이스에 업로드할 수 있다.
하지만 keystore.properties 파일은 절대 올리면 안되니 주의!!
[출처]
- [공식]
https://developer.android.com/studio/build/build-variants?hl=ko
https://developer.android.com/studio/publish/app-signing?hl=ko
- https://yoon-dailylife.tistory.com/92