[android] 키 저장소 정보를 build.gradle에 넣지 않고 APK에 서명

키 저장소 비밀번호와 키 비밀번호 프로젝트 build.gradle파일에 저장 되지 않도록 서명 프로세스를 설정하려고 합니다.

현재 나는 다음과 같은 것을 가지고있다 build.gradle:

android {
    ...
    signingConfigs {
        release {
            storeFile file("my.keystore")
            storePassword "store_password"
            keyAlias "my_key_alias"
            keyPassword "key_password"
        }
    }

    buildTypes {
        release {
            signingConfig signingConfigs.release            
        }
    }
}

완벽하게 작동하지만 의 값 과 저장소에 값을 입력 해서는 안됩니다 . 나는 넣지하는 것을 선호 하고 하나있다.storePasswordkeyPasswordstoreFilekeyAlias

build.gradle일부 외부 소스 (내 컴퓨터에만있는 파일과 같은)로부터 암호를 얻도록 변경하는 방법이 있습니까?

물론 변경 사항 build.gradle은 다른 컴퓨터에서도 사용할 수 있어야합니다 (컴퓨터가 암호에 액세스 할 수없는 경우에도).

중요한 경우 Android Studio 및 Mac OS X Maverics를 사용하고 있습니다.



답변

Groovy의 좋은 점은 Java 코드를 자유롭게 혼합 할 수 있으며를 사용하여 키 / 값 파일을 쉽게 읽을 수 있다는 것 java.util.Properties입니다. 관용적 그루비를 사용하는 훨씬 쉬운 방법이 있을지 모르지만 Java는 여전히 매우 간단합니다.

keystore.properties파일을 작성 하십시오 (이 예제에서 프로젝트 옆의 루트 디렉토리에 원하는 위치에 파일 settings.gradle을 넣을 수 있음).

storePassword=...
keyPassword=...
keyAlias=...
storeFile=...

이것을 다음에 추가하십시오 build.gradle:

allprojects {
    afterEvaluate { project ->
        def propsFile = rootProject.file('keystore.properties')
        def configName = 'release'

        if (propsFile.exists() && android.signingConfigs.hasProperty(configName)) {
            def props = new Properties()
            props.load(new FileInputStream(propsFile))
            android.signingConfigs[configName].storeFile = file(props['storeFile'])
            android.signingConfigs[configName].storePassword = props['storePassword']
            android.signingConfigs[configName].keyAlias = props['keyAlias']
            android.signingConfigs[configName].keyPassword = props['keyPassword']
        }
    }
}


답변

또는 자동 생성 된 gradle 코드와 유사한 방식으로 Scott Barta의 답변을 적용하려면 keystore.properties프로젝트 루트 폴더에 파일을 만들 수 있습니다 .

storePassword=my.keystore
keyPassword=key_password
keyAlias=my_key_alias
storeFile=store_file  

gradle 코드를 다음과 같이 수정하십시오.

// Load keystore
def keystorePropertiesFile = rootProject.file("keystore.properties");
def keystoreProperties = new Properties()
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))

...

android{

    ...

    signingConfigs {
        release {
            storeFile file(keystoreProperties['storeFile'])
            storePassword keystoreProperties['storePassword']
            keyAlias keystoreProperties['keyAlias']
            keyPassword keystoreProperties['keyPassword']
        }
    }

    ...

}

이 속성 파일을 모듈의 루트에 저장할 수 있습니다.이 경우에는 생략 rootProject하고 다른 키 저장소 및 키 별명에 대한 여러 속성 세트를 갖도록이 코드를 수정할 수도 있습니다.


답변

가장 쉬운 방법은 ~/.gradle/gradle.properties파일 을 만드는 것 입니다.

ANDROID_STORE_PASSWORD=hunter2
ANDROID_KEY_PASSWORD=hunter2

그러면 build.gradle파일이 다음과 같이 보일 수 있습니다.

android {
    signingConfigs {
        release {
            storeFile file('yourfile.keystore')
            storePassword ANDROID_STORE_PASSWORD
            keyAlias 'youralias'
            keyPassword ANDROID_KEY_PASSWORD
        }
    }
    buildTypes {
        release {
            signingConfig signingConfigs.release
        }
    }
}


답변

몇 가지 링크를 읽은 후 :

http://blog.macromates.com/2006/keychain-access-from-shell/
http://www.thoughtworks.com/es/insights/blog/signing-open-source-android-apps-without-disclosing- 비밀번호

Mac OSX를 사용하고 있으므로 키 체인 접근을 사용하여 암호를 저장할 수 있습니다.

키 체인 접근에서 비밀번호를 추가하는 방법

그런 다음 gradle 스크립트에서 :

/* Get password from Mac OSX Keychain */
def getPassword(String currentUser, String keyChain) {
    def stdout = new ByteArrayOutputStream()
    def stderr = new ByteArrayOutputStream()
    exec {
        commandLine 'security', '-q', 'find-generic-password', '-a', currentUser, '-gl', keyChain
        standardOutput = stdout
        errorOutput = stderr
        ignoreExitValue true
    }
    //noinspection GroovyAssignabilityCheck
    (stderr.toString().trim() =~ /password: '(.*)'/)[0][1]
}

다음과 같이 사용하십시오.

getPassword (현재 사용자, “Android_Store_Password”)

/* Plugins */
apply plugin: 'com.android.application'

/* Variables */
ext.currentUser = System.getenv("USER")
ext.userHome = System.getProperty("user.home")
ext.keystorePath = 'KEY_STORE_PATH'

/* Signing Configs */
android {
    signingConfigs {
        release {
            storeFile file(userHome + keystorePath + project.name)
            storePassword getPassword(currentUser, "ANDROID_STORE_PASSWORD")
            keyAlias 'jaredburrows'
            keyPassword getPassword(currentUser, "ANDROID_KEY_PASSWORD")
        }
    }

    buildTypes {
        release {
            signingConfig signingConfigs.release
        }
    }
}


답변

이것이 내가하는 방법입니다. 환경 변수 사용

  signingConfigs {
    release {
        storeFile file(System.getenv("KEYSTORE"))
        storePassword System.getenv("KEYSTORE_PASSWORD")
        keyAlias System.getenv("KEY_ALIAS")
        keyPassword System.getenv("KEY_PASSWORD")
    }


답변

기존 Android Studio gradle 프로젝트를 가져 와서 파일을 편집하지 않고도 명령 줄에서 빌드 / 서명 할 수 있습니다. 이렇게하면 build.gradle 파일이 아닌 키와 비밀번호를 별도로 유지하면서 프로젝트를 버전 제어에 저장하는 것이 매우 좋습니다.

./gradlew assembleRelease -Pandroid.injected.signing.store.file=$KEYFILE -Pandroid.injected.signing.store.password=$STORE_PASSWORD -Pandroid.injected.signing.key.alias=$KEY_ALIAS -Pandroid.injected.signing.key.password=$KEY_PASSWORD


답변

허용 된 답변은 파일을 사용하여 프로젝트의 동일한 루트 폴더에있는 APK에 서명하는 데 사용할 키 저장소를 제어합니다. 우리가 사용하는 경우 VCS 같이 힘내 , 우리가 목록을 무시하는 특성 파일을 추가하는 것을 잊지 나쁜 일이 될 수 있습니다. 비밀번호를 세상에 공개 할 것이기 때문입니다. 문제는 여전히 지속됩니다.

프로젝트 내에서 동일한 디렉토리에 속성 파일을 만드는 대신 외부에 만들어야합니다. gradle.properties 파일을 사용하여 외부에 만듭니다.

단계는 다음과 같습니다.

1. 루트 프로젝트에서 gradle.properties를 편집하거나 작성하고 다음 코드를 추가하십시오. 경로를 직접 편집하십시오.

AndroidProject.signing=/your/path/androidproject.properties  

2. / your / path /에 androidproject.properties를 만들고 다음 코드를 추가하십시오 ./your/path/to/android.keystore를 키 저장소 경로로 변경하는 것을 잊지 마십시오.

STORE_FILE=/your/path/to/android.keystore
STORE_PASSWORD=yourstorepassword
KEY_ALIAS=yourkeyalias
KEY_PASSWORD=yourkeypassword  

3. 앱 모듈 build.gradle (프로젝트 루트 build.gradle 아님)에 다음 코드가 없으면 추가하거나 조정하십시오.

signingConfigs {
     release
   }
   buildTypes {
   debug {
     debuggable true
   }
   release {
     minifyEnabled true
     proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
     signingConfig signingConfigs.release
   }
 }  

4 단계에서 코드 아래에 다음 코드를 추가하십시오.

if (project.hasProperty("AndroidProject.signing")
     && new File(project.property("AndroidProject.signing").toString()).exists()) {
     def Properties props = new Properties()
     def propFile = new File(project.property("AndroidProject.signing").toString())
     if(propFile.canRead()) {
      props.load(new FileInputStream(propFile))
      if (props!=null && props.containsKey('STORE_FILE') && props.containsKey('STORE_PASSWORD') &&
         props.containsKey('KEY_ALIAS') && props.containsKey('KEY_PASSWORD')) {
         android.signingConfigs.release.storeFile = file(props['STORE_FILE'])
         android.signingConfigs.release.storePassword = props['STORE_PASSWORD']
         android.signingConfigs.release.keyAlias = props['KEY_ALIAS']
         android.signingConfigs.release.keyPassword = props['KEY_PASSWORD']
      } else {
         println 'androidproject.properties found but some entries are missing'
         android.buildTypes.release.signingConfig = null
      }
     } else {
            println 'androidproject.properties file not found'
          android.buildTypes.release.signingConfig = null
     }
   }  

이 코드는 1 단계의 gradle.properties 에서 AndroidProject.signing 속성을 검색합니다 . 속성이 발견되면 속성 값을 2 단계 에서 만든 androidproject.properties를 가리키는 파일 경로로 변환합니다 . 그런 다음 모든 속성 값이 build.gradle의 서명 구성으로 사용됩니다.

이제 키 저장소 비밀번호가 노출 될 위험에 대해 다시 걱정할 필요가 없습니다.

build.gradle에 키 저장소 정보를 넣지 않고 Android APK 서명 에서 자세히 알아보십시오.