programing

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

oldcodes 2023. 8. 7. 23:04
반응형

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

키스토어, 비밀번호, 키 비밀번호가 프로젝트의 웹사이트에 저장되지 않도록 서명 프로세스를 설정하려고 합니다.build.gradlejava.

저는 현재저다있습다니가지고에 과 같은 이 있습니다.build.gradle:

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

    buildTypes {
        release {
            signingConfig signingConfigs.release            
        }
    }
}

완벽하게 작동하지만 값을 입력해서는 안 됩니다.storePassword,그리고.keyPassword내 저장소에.나는 그것을 넣지 않는 것이 좋습니다.storeFile그리고.keyAlias거기도 마찬가지야.

그것을 바꿀 수 있는 방법이 있습니까?build.gradle외부 소스(예: 내 컴퓨터에만 있는 파일)에서 암호를 가져오시겠습니까?

변형된 고물론것, 된들은형변.build.gradle암호에 대한 액세스 권한이 없는 경우에도 다른 컴퓨터에서 사용할 수 있어야 합니다.

저는 안드로이드 스튜디오를 사용하고 있고, Mac OS X 매버릭스에서 사용하고 있습니다.

또는 Scott Barta의 답변을 자동 생성된 Gradle 코드와 더 유사한 방식으로 적용하려면 다음을 생성할 수 있습니다.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또한 이 코드를 수정하여 서로 다른 키 저장소 및 키 별칭에 대한 여러 속성 집합을 가질 수 있습니다.

코드를 수 키값 파일에서 가 매우 쉽다는 것입니다.java.util.Properties어쩌면 관용구 그루비를 사용하는 훨씬 더 쉬운 방법이 있을지도 모르지만, 자바는 여전히 꽤 간단합니다.

성을 합니다.keystore.properties 일파이프루있옆음에디트리렉터의트로젝는예서에▁to이)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/gradle.propertiesjava.

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/ https://www.thoughtworks.com/en-gb/insights/blog/signing-open-source-android-apps-without-disclosing-passwords

Mac OSX를 사용하고 있으므로 Keychain Access를 사용하여 암호를 저장할 수 있습니다.

How to add password in Keychain Access

그러면 당신의 그라들 스크립트에서:

/* 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]
}

다음과 같이 사용:

암호 가져오기(현재 사용자, "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

외부 JSON 파일에 자격 증명을 넣고 눈금에서 읽어내려는 사람들을 위해 다음과 같이 했습니다.

my_project/credentials.json:

{
    "android": {
        "storeFile": "/path/to/acuity.jks",
        "storePassword": "your_store_password",
        "keyAlias": "your_android_alias",
        "keyPassword": "your_key_password"
    }
}

my_project/project/app/build.gradle

// ...
signingConfigs {
        release {

            def credsFilePath = file("../../credentials.json").toString()
            def credsFile = new File(credsFilePath, "").getText('UTF-8')
            def json = new groovy.json.JsonSlurper().parseText(credsFile)
            storeFile file(json.android.storeFile)
            storePassword = json.android.storePassword
            keyAlias = json.android.keyAlias
            keyPassword = json.android.keyPassword
        }
        ...
        buildTypes {
            release {
                signingConfig signingConfigs.release //I added this
                // ...
            }
        }
    }
// ...
}

가 내가선이유는을 .json 형식(a가 아닌 파일 ).properties 형식은 사용자 도 동일한하고 싶었기 입니다.my_project/credentials.json.), "Gradle parse".

승인된 응답은 파일을 사용하여 프로젝트의 동일한 루트 폴더에 있는 APK에 서명하는 데 사용할 키 저장소를 제어합니다.Git와 같은 VCS를 사용하는 경우 무시할 속성 파일을 추가하는 것을 잊으면 좋지 않을 수 있습니다.왜냐하면 우리는 비밀번호를 세상에 공개할 것이기 때문입니다.문제는 여전히 남아 있습니다.

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

다음 단계를 참조:

1.루트 프로젝트에서 gradle.properties를 편집 또는 생성하고 다음 코드를 추가합니다. 경로는 자신의 것으로 편집해야 합니다.

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

2. /your/path/에 Android project.properties를 만들고 여기에 다음 코드를 추가합니다. /your/path/to/android를 변경하는 것을 잊지 마십시오.키 저장소 경로에 대한 키 저장소:

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

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

이제 키 저장소 암호가 노출될 위험을 다시 걱정할 필요가 없습니다.

저장소 정보를 build.gradle에 넣지 않고 Android apk 서명에서 자세히 읽어 보십시오.

이 질문은 많은 유효한 답변을 받았지만, 저는 도서관 관리자들에게 유용할 수 있는 제 코드를 공유하고 싶었습니다. 왜냐하면 원본이 꽤 깨끗하기 때문입니다.

는 모듈 에 I " 가합니다추폴를더에리토디듈모" 합니다.gitignore다음과 같이 표시됩니다.

/signing
    /keystore.jks
    /signing.gradle
    /signing.properties

keystore.jks그리고.signing.properties스스로 설명할 수 있어야 합니다.signing.gradle다음과 같이 표시됩니다.

def propsFile = file('signing/signing.properties')
def buildType = "release"

if (!propsFile.exists()) throw new IllegalStateException("signing/signing.properties file missing")

def props = new Properties()
props.load(new FileInputStream(propsFile))

def keystoreFile = file("signing/keystore.jks")
if (!keystoreFile.exists()) throw new IllegalStateException("signing/keystore.jks file missing")

android.signingConfigs.create(buildType, {
    storeFile = keystoreFile
    storePassword = props['storePassword']
    keyAlias = props['keyAlias']
    keyPassword = props['keyPassword']
})

android.buildTypes[buildType].signingConfig = android.signingConfigs[buildType]

그고원은본리▁original▁and.build.gradle

apply plugin: 'com.android.application'
if (project.file('signing/signing.gradle').exists()) {
    apply from: 'signing/signing.gradle'
}

android {
    compileSdkVersion 27
    defaultConfig {
        applicationId ...
    }
}

dependencies {
    implementation ...
}

는 없습니다.사용자가 유효한 액세스 권한을 가진 경우 입력합니다.signing디렉토리를 모듈에 넣으면 유효한 서명된 릴리스 응용 프로그램을 만들 수 있습니다. 그렇지 않으면 일반적으로 작동하는 것처럼 작동합니다.

https://stackoverflow.com/a/33218300/1673761 에서 영감을 받아 몇 가지 개선 사항을 제공합니다.

장점

  • keystore 속성(파일 이름, 별칭, 암호)은 git 외부에 저장됩니다.
  • keystore 파일 또는 keystore.properties가 없는 경우에도 디버그 모드는 계속 작동합니다.
  • 키 저장소와 해당 속성이 루트 폴더에 나란히 있습니다.

프로트또루는트의젝또)에서androidReact Native(기본값)는 다음과 같습니다.

  • 된 키 app.keystore
  • 이름을 지정한 파일을 만듭니다.keystore.properties
  • 두 개의 을 이두파가 일 다 추.gitignore

keystore.properties더하다

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

app/build.gradle더하다

// 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: 그루비 로직을 개선하기 위한 편집을 환영합니다.

'keystore.properties'에서

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

app/build.gradle.kts더하다

...

android {
  ...
  signingConfigs {
    create("release") {
    // Load keystore
    val keystoreProperties = Properties().apply{
        load(File("keystore.properties").reader())
    }
    storeFile = File(keystoreProperties.getProperty("STORE_FILE"))
    storePassword = keystoreProperties.getProperty("STORE_PASSWORD")
    keyAlias = keystoreProperties.getProperty("KEY_ALIAS")
    keyPassword= keystoreProperties.getProperty("KEY_PASSWORD")
   }
  }
  buildTypes {
    release {
      signingConfig signingConfigs.release
    }
  }
}

명령줄에서 암호를 요청할 수 있습니다.

...

signingConfigs {
  if (gradle.startParameter.taskNames.any {it.contains('Release') }) {
    release {
      storeFile file("your.keystore")
      storePassword new String(System.console().readPassword("\n\$ Enter keystore password: "))
      keyAlias "key-alias"
      keyPassword new String(System.console().readPassword("\n\$ Enter keys password: "))
    } 
  } else {
    //Here be dragons: unreachable else-branch forces Gradle to create
    //install...Release tasks.
    release {
      keyAlias 'dummy'
      keyPassword 'dummy'
      storeFile file('dummy')
      storePassword 'dummy'
    } 
  }
}

...

buildTypes {
  release {

    ...

    signingConfig signingConfigs.release
  }

  ...
}

...

이전에 다음과 같은 답변이 표시되었습니다. https://stackoverflow.com/a/33765572/3664487

제 비밀번호에는 달러 기호가 $인 특수 문자가 포함되어 있었고 저는 gradle.properties 파일에서 탈출해야 했습니다.그 이후로, 저는 사인이 효과가 있었습니다.

CI 도구를 사용하지 않는 한 파일이 버전 제어 하에 있지 않더라도 자격 증명을 텍스트 파일에 일반 텍스트로 저장하는 것은 좋지 않습니다.

이것이 일반적인 관행이라는 것은 알고 있지만(공식 문서에서도 언급하고 있음) 개인 이메일의 암호를 텍스트 파일에 저장할 생각은 하지 않을 것입니다. 왜 앱으로 암호를 저장합니까?

제 접근 방식은 build.gradle을 최대한 깨끗하게 유지하면서 두 암호를 모두 쿼리하고 릴리스를 빌드하는 간단한 명령을 사용하는 것입니다.예:

Key store password:
Key password:

다른 답변을 살펴보았지만, a) 자격 증명을 일반 텍스트로 저장 b) 작동하지 않거나 c) 너무 복잡한 내용입니다.


  1. 이 서명 구성을 build.gradle에 추가합니다.

    android {
        ...
        signingConfigs {
            release {
                storeFile file(findProperty('keystore_path') ?: 'default path')
                storePassword findProperty('keystore_pw')
                keyAlias findProperty('key_alias')
                keyPassword findProperty('key_pw')
            }
        }
        ...
    
        buildTypes {
            release {
                ...
                signingConfig signingConfigs.release
            }
        }
    }
    
  2. dir에서 이합니다(편집 "dir" "dit "dir" " " " " "/PATH/TO/KEYSTORE.jks그리고.KEY_ALIAS):

    echo -n Key store password: && read -s storepw && echo && \
    echo -n Key password: && read -s keypw && echo && \
    ./gradlew assembleRelease -Pkeystore_path='/PATH/TO/KEYSTORE.jks' -Pkeystore_pw=$storepw -Pkey_alias='KEY_ALIAS' -Pkey_pw=$keypw
    

이것은 An과 Damodaran의 답변과 다른 Kotlin 빌드 스크립트(build.gradle.kts)에 대한 또 다른 답변입니다.

local.properties 파일에서 OS 환경 변수로 다시 이동하여 읽으려고 합니다.특히 GitHub Actions와 같은 CI에서 유용할 수 있습니다(저장소 설정에서 환경 비밀을 생성할 수 있음).

Kotlin 1.6.10 및 Gradle 7.4.2와 Android Gradle Plugin(AGP) 7.0.4를 사용하고 있습니다.

import com.android.build.gradle.internal.cxx.configure.gradleLocalProperties
// ...

val environment = System.getenv()
fun getLocalProperty(key: String) = gradleLocalProperties(rootDir).getProperty(key)
fun String.toFile() = File(this)

android {
    signingConfigs {
        create("MySigningConfig") {
            keyAlias = getLocalProperty("signing.keyAlias") ?: environment["SIGNING_KEY_ALIAS"] ?: error("Error!")
            storeFile = (getLocalProperty("signing.storeFile") ?: environment["SIGNING_STORE_FILE"] ?: error("Error!")).toFile()
            keyPassword = getLocalProperty("signing.keyPassword") ?: environment["SIGNING_KEY_PASSWORD"] ?: error("Error!")
            storePassword = getLocalProperty("signing.storePassword") ?: environment["SIGNING_STORE_PASSWORD"] ?: error("Error!")
            enableV1Signing = true
            enableV2Signing = true
        }
    }

    buildTypes {
        release {
            signingConfig = signingConfigs["MySigningConfig"]
            isMinifyEnabled = true
            proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
        }
    }
}

앞서 말한 것처럼 프로젝트 루트에 local.properties 파일을 두고 속성 값을 지정할 수 있습니다.

signing.keyAlias=My key
signing.keyPassword=zyxwvuts
signing.storePassword=abcdefgh
signing.storeFile=C\:\\Users\\Mahozad\\keystore.jks

OS에 를 설정할 수 . 를 들어 " " " OS" " "/ " " 라는 할 수 있습니다. 예를 들어 다음과 같은 환경 변수를 생성할 수 있습니다.SIGNING_KEY_ALIAS선택사항:

  • Windows 명령 프롬프트:setx SIGNING_KEY_ALIAS "My key"
  • 터미널: Linux 파일:export SIGNING_KEY_ALIAS="My key"

언급URL : https://stackoverflow.com/questions/20562189/sign-apk-without-putting-keystore-info-in-build-gradle

반응형