Sign APK without putting keystore info in build.gradle

后端 未结 12 914
栀梦
栀梦 2020-11-28 17:51

I am trying to setup signing process so that keystore password and key password are not stored in the project\'s build.gradle file.

Cur

相关标签:
12条回答
  • 2020-11-28 18:00

    Alternatively, if you want to apply Scott Barta's answer in a way more similar to the auto generated gradle code, you can create a keystore.properties file in your project root folder:

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

    and modify your gradle code to:

    // 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']
            }
        }
    
        ...
    
    }
    

    You can store this properties file in the root of your module, in which case just omit rootProject, and you can also modify this code to have several sets of properties for different keystores and key aliases.

    0 讨论(0)
  • 2020-11-28 18:02

    Inspired from https://stackoverflow.com/a/33218300/1673761 with some improvements

    Pros

    • keystore properties (file name, alias, passwords) are stored outside of git
    • Debug mode still works even if we don't have a keystore file or keystore.properties
    • The keystore and its properties are in the root folder side by side

    In the root of your project (or in android folder for React Native):

    • Add your generated keystore file ie: app.keystore
    • create a file named keystore.properties
    • Add these two files to .gitignore

    In keystore.properties add

    STORE_FILE=app.keystore
    KEY_ALIAS=app_alias
    STORE_PASSWORD=your_password
    KEY_PASSWORD=your_password
    

    In app/build.gradle add

    // Load keystore
    def keystoreProperties = new Properties()
    try {
        def keystorePropertiesFile = rootProject.file("keystore.properties");
        keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
    } catch(IOException e) {
        // We don't have release keys, ignoring
    }
    
    ...
    
    android {
      ...
      signingConfigs {
        release {
          if (keystoreProperties['STORE_FILE']) {
            storeFile rootProject.file(keystoreProperties['STORE_FILE'])
            storePassword keystoreProperties['STORE_PASSWORD']
            keyAlias keystoreProperties['KEY_ALIAS']
            keyPassword keystoreProperties['KEY_PASSWORD']
          }
        }
      }
      buildTypes {
        release {
          signingConfig signingConfigs.release
        }
      }
    }
    

    PS: Edits to improve the groovy logic are welcome

    0 讨论(0)
  • 2020-11-28 18:06

    The accepted answer use a file to controls which keystore to use to sign the APK that resides in the same root folder of project. When we using vcs like Git, could be a bad thing when we forget to add the properties file to ignore list. Because we will disclose our password to the world. The problems still persist.

    Instead making properties file in the same directory within our project, we should make it outside. We make it outside by using gradle.properties file.

    Here the steps:

    1.Edit or create gradle.properties on your root project and add the following code, remember to edit the path with your own:

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

    2.Create androidproject.properties in /your/path/ and add the following code to it, don't forget to change /your/path/to/android.keystore to your keystore path:

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

    3.In your app module build.gradle (not your project root build.gradle) add the following code if not exist or adjust to it:

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

    4.Add the following code below the code in step 3:

    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  
         }  
       }  
    

    This code will search for AndroidProject.signing property in gradle.properties from step 1. If the property found, it will translate property value as file path which pointing to androidproject.properties that we create in step 2. Then all the property value from it will be used as signing configuration for our build.gradle.

    Now we don't need to worry again of risk of exposing our keystore password.

    Read more at Signing Android apk without putting keystore info in build.gradle

    0 讨论(0)
  • 2020-11-28 18:11

    The nice thing about Groovy is that you can freely mix Java code, and it's pretty easy to read in a key/value file using java.util.Properties. Perhaps there's an even easier way using idiomatic Groovy, but Java is still pretty simple.

    Create a keystore.properties file (in this example, in the root directory of your project next to settings.gradle, though you can put it wherever you like:

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

    Add this to your 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']
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-28 18:16

    It is possible to take any existing Android Studio gradle project and build/sign it from the command line without editing any files. This makes it very nice for storing your project in version control while keeping your keys and passwords separate and not in your build.gradle file:

    ./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
    
    0 讨论(0)
  • 2020-11-28 18:17

    The easiest way is to create a ~/.gradle/gradle.properties file.

    ANDROID_STORE_PASSWORD=hunter2
    ANDROID_KEY_PASSWORD=hunter2
    

    Then your build.gradle file can look like this:

    android {
        signingConfigs {
            release {
                storeFile file('yourfile.keystore')
                storePassword ANDROID_STORE_PASSWORD
                keyAlias 'youralias'
                keyPassword ANDROID_KEY_PASSWORD
            }
        }
        buildTypes {
            release {
                signingConfig signingConfigs.release
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题