애플리케이션에서 개인 API 키를 저장하고 보호하는 모범 사례 [닫기]


373

대부분의 앱 개발자는 일부 타사 라이브러리를 앱에 통합합니다. Dropbox 또는 YouTube와 같은 서비스에 액세스하거나 로깅이 충돌하는 경우. 타사 라이브러리 및 서비스의 수는 엄청납니다. 이러한 라이브러리와 서비스는 대부분 서비스를 인증함으로써 통합되며, 대부분 API 키를 통해 이루어집니다. 보안 목적으로 서비스는 일반적으로 공개 및 개인을 생성하며, 종종 비밀 키라고도합니다. 불행히도 서비스에 연결하려면이 개인 키를 인증에 사용해야하므로 응용 프로그램의 일부일 수 있습니다. 말할 것도없이, 이것은 엄청난 보안 문제에 직면 해 있습니다. 공개 및 개인 API 키는 몇 분 만에 APK에서 추출 할 수 있으며 쉽게 자동화 할 수 있습니다.

이와 비슷한 것이 있다고 가정하면 비밀 키를 어떻게 보호 할 수 있습니까?

public class DropboxService  {

    private final static String APP_KEY = "jk433g34hg3";
    private final static String APP_SECRET = "987dwdqwdqw90";
    private final static AccessType ACCESS_TYPE = AccessType.DROPBOX;

    // SOME MORE CODE HERE

}

개인 키를 저장하는 가장 안전하고 안전한 방법은 무엇입니까? 난독 화, 암호화, 어떻게 생각하십니까?



나는 이미지 / PNG로 저장을했고 BufferReader로 PNG로를 통해 키를 얻을
수밋

나는 이것이 유효한 우려라고 생각하며 Firebase Android SDK github 페이지에 비슷한 문제를 게시했습니다 : github.com/firebase/firebase-android-sdk/issues/1583 . 이것이 처리되는지 봅시다.
grebulon

답변:


348
  1. 컴파일 된 응용 프로그램에는 키 문자열뿐만 아니라 상수 이름 APP_KEY 및 APP_SECRET도 포함되어 있습니다. 이러한 자체 문서화 코드에서 키를 추출하는 것은 간단합니다 (예 : 표준 Android 도구 dx).

  2. ProGuard를 적용 할 수 있습니다. 키 문자열은 그대로 두지 만 상수 이름은 제거합니다. 또한 가능하면 짧고 의미없는 이름으로 클래스와 메서드의 이름을 바꿉니다. 그런 다음 키를 추출하는 데 어느 문자열이 어떤 목적을 달성하는지 알아 내기 위해 시간이 더 걸립니다.

    ProGuard 설정은 두려워하는 것처럼 어렵지 않아야합니다. 우선 project.properties에 설명 된대로 ProGuard 만 활성화하면됩니다. 타사 라이브러리에 문제가있는 경우 proguard-project.txt에서 일부 경고를 억제하거나 난독 화를 방지해야 할 수 있습니다. 예를 들어 :

    -dontwarn com.dropbox.**
    -keep class com.dropbox.** { *; }

    이것은 무차별 접근 방식입니다. 처리 된 응용 프로그램이 작동하면 이러한 구성을 세분화 할 수 있습니다.

  3. 예를 들어 Base64 인코딩 또는 더 복잡한 것으로 코드에서 문자열을 수동으로 난독 처리 할 수 ​​있습니다. 아마도 네이티브 코드 일 수도 있습니다. 그런 다음 해커는 인코딩을 정적으로 리버스 엔지니어링하거나 적절한 위치에서 디코딩을 동적으로 가로 채야합니다.

  4. ProGuard의 특수 형제 DexGuard 와 같은 상용 난독 화 장치를 적용 할 수 있습니다 . 문자열과 클래스를 추가로 암호화 / 난독 처리 할 수 ​​있습니다. 그런 다음 키를 추출하는 데 더 많은 시간과 전문 지식이 필요합니다.

  5. 자체 서버에서 응용 프로그램의 일부를 실행할 수 있습니다. 키를 보관할 수 있으면 안전합니다.

결국, 키가 얼마나 중요한지, 얼마나 많은 시간이나 소프트웨어를 감당할 수 있는지, 키에 관심이있는 해커가 얼마나 정교한 지, 얼마나 많은 시간을 원할 것인지는 경제적으로 절충해야합니다. 키를 해킹하기 전에 얼마나 많은 가치를 지니고 있는지, 성공적인 해커가 키를 배포하는 규모 등은 중요합니다. 키와 같은 작은 정보는 전체 응용 프로그램보다 보호하기가 더 어렵습니다. 본질적으로 클라이언트 측에서는 깨지지 않는 것이 없지만 막대를 올릴 수는 있습니다.

(저는 ProGuard 및 DexGuard의 개발자입니다)


2
@EricLafortune은 개인 키 문자열이 Java 클래스와 String 리소스 XML에 저장되어 있다면 차이가 없습니까?
Alan

1
@EricLafortune 이제 Android Keystore 시스템을 사용하여 키를 안전하게 저장할 수 있습니까? ( developer.android.com/training/articles/keystore.html )
David Thomas

1
@DavidThomas : 키 저장소를 사용해 보셨습니까? Java 클래스로 작성된 API 키를 난독 화하고 싶습니다. 답장 해주세요
Sagar Trehan

1
Android KeyStore가 유용합니까? ( developer.android.com/training/articles/… )
Weishi Zeng

1
# 5를 이해하지 못합니다. 원래 문제와 동일한 정확한 문제가 있습니까?
pete

80

내 의견으로는 첫 번째 아이디어 만 보장 할 수있는 아이디어는 거의 없습니다.

  1. 인터넷상의 일부 서버에 비밀을 유지하고 필요할 때 간단히 사용하십시오. 사용자가 dropbox를 사용하려고 시도하면 사이트에 요청하고 비밀 키를 얻는 것을 막을 수있는 것은 없습니다.

  2. 비밀을 jni 코드에 넣고 변수 코드를 추가하여 라이브러리를 더 크고 더 디 컴파일하기 어렵게 만듭니다. 키 문자열을 몇 부분으로 나누고 여러 곳에 보관할 수도 있습니다.

  3. obfuscator를 사용하고 코드 해시 비밀을 넣은 다음 나중에 필요할 때 해시 해제하십시오.

  4. 비밀 키를 이미지 중 하나의 마지막 픽셀로 자산에 넣습니다. 그런 다음 필요할 때 코드에서 읽으십시오. 코드를 난독 처리하면 읽을 코드를 숨길 수 있습니다.

APK 코드를 읽는 것이 얼마나 쉬운 지 간략히 보려면 ​​APKAnalyser를 가져옵니다.

http://developer.sonymobile.com/knowledge-base/tool-guides/analyse-your-apks-with-apkanalyser/


46
사용자가 앱을 디 컴파일 할 수 있지만 자신의 서버에 대한 요청을 결정하고 간단히 실행하여 비밀을 얻습니다. 여기에은 총알이 없지만 몇 단계를 거치면 괜찮을 것입니다! 앱이 인기가 많지 않더라도 .. 훌륭한 아이디어!
매트 울프

3
네, 1 번은 보장 할 수 없습니다.
marcinj

42
이미지 안에 키를 숨기는 아이디어가 정말 좋습니다. +1
Igor Čordaš

1
@ MarcinJędrzejewski 당신은 네번째 해결책에 대해 더 많은 것을 설명하고 싶습니까? 감사합니다.
Dr.jacky

2
@ Mr.Hyde 이것을 스테 가노 그라피 (steganography)라고합니다. 샘플 코드를 작성하기에는 너무 복잡합니다. Google에서 예제를 찾을 수 있습니다. 여기서 하나를 찾았습니다 : dreamincode.net/forums/topic/27950-steganography . 아이디어는 훌륭하지만 apk 코드는 디 컴파일 될 수 있으므로 아름다움을 망칠 수 있습니다.
marcinj

33

다른 접근 방식은 처음에는 장치에 비밀을 두지 않는 것입니다! 모바일 API 보안 기술 (특히 3 부)을 참조하십시오 .

시간을 존중하는 전통적 전통을 사용하여 API 엔드 포인트와 앱 인증 서비스간에 비밀을 공유하십시오.

클라이언트는 API 호출을 원할 때 앱 인증 서비스에 강력한 원격 증명 기술을 사용하여이를 인증하도록 요청 하고 비밀로 서명 한 시간 제한 (보통 JWT ) 토큰을받습니다.

토큰은 요청을 수행하기 전에 엔드 포인트가 서명을 확인할 수있는 각 API 호출 과 함께 전송됩니다 .

실제 비밀은 장치에 존재하지 않습니다. 사실, 앱은 그것이 유효한지 아닌지 전혀 알지 못하며, 인증을 요청하고 결과 토큰을 전달합니다. 간접적 인 이점으로 비밀을 바꾸고 싶다면 사용자가 설치된 앱을 업데이트하지 않고도 변경할 수 있습니다.

따라서 비밀을 보호하려면 앱에서 처음에 비밀 키를 사용하지 않는 것이 좋습니다.


5
이것이 정답입니다.
ortonomy

3
인증 서비스에 액세스하려고 할 때 문제가 지속됩니다. 그것은 당신에게 클라이언트 ID와 클라이언트 비밀을 제공합니다. 우리는 어디에 저장해야합니까?
Ashi

API를 사용하기 위해 먼저 API를 인증해야하는 비공개 API는 해결되지 않습니다. 모든 앱 사용자의 자격 증명은 어디서 얻습니까?
Kibotu

25

오래된 보안되지 않은 방법 :

API / 비밀 키를 보호하는 간단한 3 단계 ( 구식 답변 )

Gradle을 사용하여 API 키 또는 비밀 키를 보호 할 수 있습니다.

1. gradle.properties (프로젝트 속성) : 키를 사용하여 변수를 만듭니다.

GoolgeAPIKey = "Your API/Secret Key"

2. build.gradle (모듈 : app) : build.gradle에 변수를 설정하여 액티비티 또는 프래그먼트에서 변수에 액세스합니다. buildTypes {}에 아래 코드를 추가하십시오.

buildTypes.each {
    it.buildConfigField 'String', 'GoogleSecAPIKEY', GoolgeAPIKey
}

3. 앱의 BuildConfig를 통해 Activity / Fragment에서 액세스하십시오.

BuildConfig.GoogleSecAPIKEY

업데이트 :

위의 솔루션은 오픈 소스 프로젝트에서 Git을 커밋하는 데 도움이됩니다. (David Rawson과 riyaz-ali의 의견에 감사드립니다).

Matthew와 Pablo Cegarra의 의견에 따르면 위의 방법은 안전하지 않으며 Decompiler는 누군가 비밀 키로 BuildConfig를 볼 수 있습니다.

해결책 :

NDK를 사용하여 API 키를 보호 할 수 있습니다. 네이티브 C / C ++ 클래스에 키를 저장하고 Java 클래스에서 액세스 할 수 있습니다.

NDK를 사용하여 API 키를 보호 하려면 블로그를 따르십시오 .

Android에서 토큰을 안전하게 저장하는 방법에 대한 후속 조치


4
gradle 파일에 키를 저장하는 것이 안전합니까?
Google

4
@Google은 gradle.properties이 최선을 다하고 소스 코드의 비밀 밖으로 적어도 유지하는 방법입니다 있도록 힘내에 체크인하지 않아야
데이비드 로슨

4
이 결과에 번들로 제공되는 API 키 방지하지 않습니다 apk(그것은 생성에 추가 될 것입니다 BuildConfig이 확실히 (오픈 소스 프로젝트의 예에 대해) 다른 API 키를 관리하는 좋은 아이디어이지만, 파일)
riyaz - 알리

5
Java Decompiler를 사용하면 누군가 BuildConfig 파일과 "GoogleSecAPIKEY"를 볼 수 있습니다.
Matthew

3
귀하의 BuildConfig.java파일은 일반 텍스트 형태의 키가됩니다. 이것은 OP가 이미하고있는 것보다 낫지 않습니다.
iceman

16

App-Secret 키는 비공개로 유지해야하지만 앱을 출시 할 때 일부 사용자가이를 취소 할 수 있습니다.

그 사람들을 위해 숨겨지지 않을 것입니다 ProGuard. 그것은 리 팩터이며 일부 유료 난 독자는 jk433g34hg3 문자열을 다시 얻기 위해 몇 가지 비트 연산자를 삽입하고 있습니다. 3 일 동안 일하면 해킹을 5-15 분 더 길게 만들 수 있습니다. :)

가장 좋은 방법은 그대로 유지하는 것입니다.

서버 측 (PC)에 저장하더라도 키를 해킹하여 인쇄 할 수 있습니다. 아마도 가장 오래 걸리나요? 어쨌든 최선의 경우 몇 분 또는 몇 시간이 걸립니다.

일반 사용자는 코드를 디 컴파일하지 않습니다.


1
글쎄-내가 대답하고자하는 대답이 아닙니다 ...) ... 나는 당신이 훌륭한 보안을 달성 할 수 있다고 생각했습니다 :(
Basic Coder

죄송합니다. 간단하고 안전한 솔루션을 원했던 것은 아니지만 컴파일러, 디 컴파일러를 사용할 수있는 사람들에게는 안전한 Java 코드가 없습니다. 기본 코드조차도 hexa viewer로 볼 수 있고 decrtyped 할 수 있습니다. 최소한 시도해 볼만한 가치가 있습니다.

1
Proguard는 실제 키를 난독 화하지 않습니다 ..? 가장 좋은 방법은 난독 화가 숨겨지는 간단한 암호화 / 암호 해독 루틴입니다.
Doomsknight

3
그것은 해독 루틴을 "보이게"하고, 반대로하기가 쉽고, 원래 문자열을 가지고 있습니다

14

가능한 해결책 중 하나는 앱에서 데이터를 인코딩하고 런타임에 디코딩을 사용하는 것입니다 (해당 데이터를 사용하려는 경우). 또한 progaurd를 사용하여 앱의 디 컴파일 된 소스 코드를 읽고 이해하기 어렵게 만드는 것이 좋습니다. 예를 들어 앱에 인코딩 된 키를 넣은 다음 런타임시 비밀 키를 해독하기 위해 앱에서 디코딩 방법을 사용했습니다.

// "the real string is: "mypassword" "; 
//encoded 2 times with an algorithm or you can encode with other algorithms too
public String getClientSecret() {
    return Utils.decode(Utils
            .decode("Ylhsd1lYTnpkMjl5WkE9PQ=="));
}

보호 된 앱의 디 컴파일 된 소스 코드는 다음과 같습니다.

 public String c()
 {
    return com.myrpoject.mypackage.g.h.a(com.myrpoject.mypackage.g.h.a("Ylhsd1lYTnpkMjl5WkE9PQ=="));
  }

적어도 그것은 나를 위해 충분히 복잡합니다. 이것은 선택의 여지가 없지만 내 응용 프로그램에 값을 저장할 때하는 방식입니다. 물론 우리 모두는 그것이 최선의 방법은 아니지만 나를 위해 일한다는 것을 알고 있습니다.

/**
 * @param input
 * @return decoded string
 */
public static String decode(String input) {
    // Receiving side
    String text = "";
    try {
        byte[] data = Decoder.decode(input);
        text = new String(data, "UTF-8");
        return text;
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }
    return "Error";
}

디 컴파일 된 버전 :

 public static String a(String paramString)
  {
    try
    {
      str = new String(a.a(paramString), "UTF-8");
      return str;
    }
    catch (UnsupportedEncodingException localUnsupportedEncodingException)
    {
      while (true)
      {
        localUnsupportedEncodingException.printStackTrace();
        String str = "Error";
      }
    }
  }

Google에서 약간의 검색으로 많은 암호화 기 클래스를 찾을 수 있습니다.


13

@Manohar Reddy 솔루션에 firebase 데이터베이스 또는 firebase RemoteConfig (Null 기본값 사용)를 추가 할 수 있습니다.

  1. 키를 암호화
  2. Firebase 데이터베이스에 저장
  3. 앱 시작 중 또는 필요할 때마다 가져 오기
  4. 해독 키를 사용

이 솔루션의 차이점은 무엇입니까?

  • 파이어베이스에 대한 자격 증명 없음
  • Firebase 액세스가 보호되므로 서명 된 인증서가있는 앱만 API 호출 권한을 갖습니다.
  • 중개인 차단을 방지하기위한 암호화 / 암호 해독 그러나 이미 https를 firebase로 호출합니다.

모두이 솔루션과 관련하여 우리는 여전히 첫 번째 광장입니다. 자격 증명을 사용하는 대신 인증서를 사용하는 것이 좋습니다. 자격 증명을 훔칠 수있는 사람은 서명 된 인증서를 훔칠 수 있습니다.
Ashi

그러나 제안 된 솔루션을 사용하면 해커 앞에 한 가지 더 복잡한 문제가 추가됩니다.
Ashi

11

이 예제에는 여러 가지 측면이 있습니다. 다른 곳에서는 명시 적으로 다루지 않았다고 생각되는 몇 가지 사항에 대해 언급하겠습니다.

운송시 비밀 보호

가장 먼저 알아야 할 것은 앱 인증을 사용하여 dropbox API에 액세스한다는 것입니다. 메커니즘을 하려면 키와 비밀을 전송해야한다는 것입니다. 연결은 HTTPS이므로 TLS 인증서를 모르면 트래픽을 가로 챌 수 없습니다. 이것은 사람이 모바일 장치에서 서버로 이동하는 동안 패킷을 가로 채서 읽는 것을 방지하기위한 것입니다. 일반 사용자에게는 트래픽의 개인 정보를 보호하는 가장 좋은 방법입니다.

좋지 않은 점은 악의적 인 사람이 앱을 다운로드하지 못하게하고 트래픽을 검사하는 것입니다. 모바일 장치로 들어오고 나가는 모든 트래픽에 Man-in-the-Middle 프록시를 사용하는 것은 정말 쉽습니다. Dropbox API의 특성으로 인해이 경우 앱 키와 비밀을 추출하기 위해 코드를 분해하거나 리버스 엔지니어링하지 않아도됩니다.

서버에서 수신 한 TLS 인증서가 원하는 인증서인지 확인하는 고정 을 수행 할 수 있습니다. 이렇게하면 클라이언트에 검사가 추가되고 트래픽을 가로 채기가 더 어려워집니다. 이로 인해 비행 중 트래픽을 검사하기가 더 어려워 지지만 클라이언트에서 피닝 검사가 수행되므로 피닝 테스트를 비활성화 할 수 있습니다. 그래도 더 어렵게 만듭니다.

휴식시 비밀 보호

첫 번째 단계로, proguard 와 같은 것을 사용 하면 비밀이 어디에 있는지 명확하게 알 수 없습니다. 또한 NDK를 사용하여 키와 비밀을 저장하고 직접 요청을 보낼 수 있으므로 정보를 추출 할 수있는 적절한 기술을 가진 사람의 수가 크게 줄어 듭니다. 값을 메모리에 직접 저장하지 않으면 더 난독 화를 달성 할 수 있습니다. 다른 답변에서 제안한대로 사용 직전에 값을 암호화하고 해독 할 수 있습니다.

더 고급 옵션

앱의 어느 곳에 나 비밀을 두는 것에 대해 편집증이 있고 더 포괄적 인 솔루션에 투자 할 시간과 돈이 있다면 자격 증명을 서버에 저장하는 것이 좋습니다 (있는 경우). 이렇게하면 서버를 통해 통신해야하므로 API 호출에 대한 대기 시간이 길어지고 데이터 처리량이 증가하여 서비스 실행 비용이 증가 할 수 있습니다.

그런 다음 서버를 보호하기 위해 서버와 가장 잘 통신하는 방법을 결정해야합니다. 내부 API에서 동일한 문제가 다시 발생하지 않도록하는 것이 중요합니다. 내가 줄 수있는 가장 좋은 방법은 중간자 위협으로 인해 비밀을 직접 전송하지 않는 것입니다. 대신 비밀을 사용하여 트래픽에 서명하고 서버로 들어오는 모든 요청의 무결성을 확인할 수 있습니다. 이를 수행하는 한 가지 표준 방법은 비밀 키를 사용하여 메시지의 HMAC를 계산하는 것입니다. 저는이 분야에서도 운영되는 보안 제품을 보유한 회사에서 일하고 있습니다. 이런 종류의 것들이 저에게 관심을 갖는 이유입니다. 사실, 여기에 나와있는 동료 중 한 사람의 블로그 기사가 있습니다.

얼마나해야합니까?

이와 같은 보안 조언을 사용하면 누군가 침입하기가 얼마나 어려운지에 대한 비용 / 혜택 결정을 내려야합니다. 수백만 고객을 보호하는 은행 인 경우 예산이 앱을 지원하는 사람과는 완전히 다릅니다 여가 시간. 누군가가 보안을 깨뜨리는 것을 막는 것은 사실상 불가능하지만 실제로는 종과 휘파람을 모두 필요로하는 사람이 거의 없으며 기본적인 예방 조치를 통해 먼 길을 갈 수 있습니다.


1
출처 를 확인하지 않고 hackernoon.com/mobile-api-security-techniques-682a5da4fe10 에서 복사하여 붙여 넣습니다 .
ortonomy

1
@ortonomy 나는 그가 당신이 링크 한 기사를 인용해야하는데 동의하지만, 둘 다 같은 장소에서 작동하기 때문에 그것을 잊었을 수도있다.
Exadra37

2
또한 Skip의 기사와 그들이 기반으로 한 블로그 게시물은 내 대답 후 일주일 후에 나왔습니다.
ThePragmatist

8

가장 안전한 솔루션은 키를 서버에 유지하고 해당 키가 필요한 모든 요청을 서버를 통해 라우팅하는 것입니다. 그렇게하면 서버가 안전한 한 키가 서버를 떠나지 않으므로 키도 서버를 떠나지 않습니다. 물론이 솔루션에는 성능 비용이 있습니다.


32
문제는-다른 비밀 키를 사용해야하는 모든 secrects가 포함 된 서버에 도달하는 것입니다. 어떻게 유지할지 궁금합니다. ;) 내가 말하려는 것은-이것은 또한 최고의 솔루션이 아닙니다 (여기에 이상적인 솔루션이 있다고 생각하지 마십시오)
Mercury

서버가 완전히 제어 할 수있는 것은 아닙니다. 그것이 필요한 것은 전적으로 당신에게 달려 있습니다.
Bernard Igiri

5
키가 서버 측에있는 동안 클라이언트가 서버로 보내려는 데이터를 어떻게 암호화 할 수 있습니까? 그리고 당신의 대답이 될 것입니다-서버가 클라이언트에게 키를 보냅니다-그래서 그것은 보안되어야합니다! 다시 마법 솔루션이 없습니다! 보이지 않습니까?!
머큐리

2
@BernardIgiri 그리고 다시 우리는 다시 정사각형 1로 돌아갑니다. 전화가 임의의 로그인을 생성하고 서버가 그것을 수락하고 핀을 보낸다고 가정합니다 (이것은 우리가 말하는 개인 서버입니다 ). 그런 다음 앱을 분해하는 사람은 개인 서버 에 액세스하는 데 필요한 모든 것이 자신이 만들 수있는 임의의 로그인 일 뿐이라는 것을 알게됩니다. 그가 서버를 생성하고 서버에 액세스하는 것을 방해하는 이유를 알려주십시오. 실제로 솔루션과 실제로 로그인 또는 api 키를 주 서버에 저장하는 것 (개인 서버에 자격 증명을 저장하려는 사용자)의 차이점은 무엇입니까?
Ken

3
@ken 난수는 전화 번호 및 문자 메시지에 대한 물리적 액세스에 대해 인증됩니다. 누군가가 당신을 속이는 경우, 당신은 그들의 정보를 가지고 있습니다. 충분하지 않으면 전체 사용자 계정과 비밀번호를 작성하도록 강요하십시오. 그것으로 충분하지 않으면 신용 카드도 받으십시오. 그것으로 충분하지 않으면 전화를 걸어보세요. 충분하지 않으면 얼굴을 맞대고 만나십시오. 얼마나 안전하고 불편한가?
Bernard Igiri

7

비밀을 유지하고 firebase database앱이 시작될 때 웹에서 가져 오십시오. 웹 서비스를 호출하는 것보다 훨씬 낫습니다.


13
하지만 firebase에 대한 자격 증명은 어떻습니까?
the_joric

2
불행히도 Firebase 데이터베이스는 중국에서 작동하지 않습니다.
Konjengbam

9
이해가되지 않습니다, 공격자는 디 컴파일 코드에서 세부 사항을 중포 기지 확인하고 datababse에서 데이터를 얻을 수 있습니다
user924

3
firebase Apps가 SHA1을 사용하여 서버에 액세스 할 때 이것이 최선의 해결책이라고 생각합니다. 해커의 새로운 앱은 정확한 앱 스탬프를 사용하여 Firebase에 액세스해야하기 때문에 코드를 디 컴파일해도 Firebase를 호출하는 데 도움이되지 않습니다. 또한, 저장된 키는 firebase DB에 저장하기 전에 암호화되어야하며 중간 사람의 차단을 피하기 위해 일단 수신되면 해독해야합니다.
Ayman Al-Absi

네트워크를 통해 Firebase 데이터베이스에서 비밀을 얻을 때 보안 (https) 채널을 통해 다른 웹 서비스에서 동일한 비밀을 얻는 것보다 더 안전합니까? 설명 할 수 있습니까?
Csaba Toth

6

비밀 키를 보호하기 위해 무엇을하든 실제 솔루션은 아닙니다. 개발자가 응용 프로그램을 디 컴파일 할 수있는 경우 키를 보호 할 수있는 방법이 없습니다. 키를 숨기는 것은 모호한 보안에 의한 것이며 코드 난독 화입니다. 비밀 키 보안의 문제점은 보안 키를 보호하려면 다른 키를 사용해야하고 해당 키도 보안되어야한다는 것입니다. 키로 잠긴 상자에 키가 숨겨져 있다고 생각하십시오. 방 안에 상자를 놓고 방을 잠그십시오. 보안을 유지하기 위해 다른 키가 남아 있습니다. 그리고 그 키는 여전히 응용 프로그램 내에서 하드 코딩 될 것입니다.

따라서 사용자가 PIN이나 문구를 입력하지 않으면 키를 숨길 수 없습니다. 그러나 그렇게하려면 대역 외에서 발생하는 PIN을 관리하기위한 체계를 갖추어야합니다. 이는 다른 채널을 통하는 것을 의미합니다. Google API와 같은 서비스의 키 보안에는 실용적이지 않습니다.


5

오래된 게시물이지만 여전히 충분합니다. 물론 NDK와 C ++을 사용하여 .so 라이브러리에 숨기는 것이 좋을 것이라고 생각합니다. .so 파일은 16 진수 편집기에서 볼 수 있지만 행운을 디 컴파일하면 : P


9
사용자는 공유 라이브러리를 쉽게 호출하여 숨길 수있는 모든 것을 얻을 수 있습니다. 분리 할 필요가 없습니다.
david72

5
androidauthority.com/ 에 따르면 현재 안드로이드에서 그것을 할 수있는 안전한 방법은 없습니다.
david72

1
@AhmedAwad 왜 3 개의 투표를했는지 이해가 가지 않습니다. 누구나 쉽게 앱을 디 컴파일하고 ndk 진입 점이 어떻게 호출되는지 확인할 수 있습니다 : /
Johny19

1
이 답변은 거의 가장 좋은 옵션 중 하나이지만 저자는 체크섬이 APK와 일치하는지 확인하기 위해 전화 (NDK 라이브러리 내부)를 포함해야합니다. 그렇지 않으면 누군가가 NDK 라이브러리 외부로 전화 할 수 있습니다 앱
Stoycho Andreev

@Sniper는 큰 문제가 있다는 점을 제외하고는 훌륭 할 것입니다. 어떤 메소드가 기본 메소드를 "호출"하는지 어떻게 알 수 있습니까? apk의 이름을 하드 코딩하여 확인하는 것이 좋습니다.하지만 "hack"apk를 "good"apk와 동일한 폴더로 만들면 어떻게됩니까? "양호한"apk에 체크섬이 있는지 확인하고 해당 기본 메소드를 실행할 수 있습니다. JNI / C ++에서 호출자 파일을 알 수있는 방법이 없다면 다른 옵션과 마찬가지로 의미가 없습니다.
SocketByte

5

이러한 비공개를 유지하는 유일한 방법은 서버에 보관하고 앱이 서버에 무엇이든 보내도록하고 서버가 Dropbox와 상호 작용하는 것입니다. 그런 식으로 개인 키를 어떤 형식으로도 배포하지 마십시오.


11
그러나 다른 세계가 서버를 호출하지 못하게하려면 어떻게해야합니까?
user2966445

"서버"가 자격 증명이있는 웹 서버를 의미하는 경우 원하는 방법을 사용할 수 있습니다. 사용자 이름 / 암호, oauth, 활성 디렉토리 등을 사용한 간단한 인증. 실제로는 응용 프로그램에 따라 다릅니다.
Nick

어쩌면 내가 누락 된 것이 있지만 여전히 앱 내에 자격 증명을 저장하지 않아도됩니까?
user2966445

3
맞습니다.하지만 앱이 먼저 서버와 인증한다고 말했습니다. 이것이 앱에 다른 자격 증명 세트를 저장한다는 의미가 아닙니까? 서버가 실제 보관 용 전화를 처리한다는 것을 알고 있습니다.
user2966445

4
글쎄, 그것은 의미 할 수 있지만 완전히 별도의 권한 부여입니다. 그러나 당신은 할 필요가 없습니다. 내가 말하는 유스 케이스는 앱 사용자가 페이스 북이나 트위터를 사용하여 앱에 로그인 할 수 있다는 것입니다. 앱에 자신의 자격 증명을 저장하지 않고 심지어 자격 증명을 모릅니다. 이 인증 프로세스를 통해 Dropbox에 대한 자격 증명이있는 API 서버에 액세스 할 수 있지만 앱 또는 사용자는 직접 액세스 할 수 없습니다.
Nick

0

쓴 경험과 IDA-Pro 전문가와상의 한 후 코드의 핵심 부분을 DLL / SharedObject로 옮긴 다음 서버에서 가져와 런타임에로드하는 것이 가장 좋습니다.

민감한 데이터는 다음과 같이 매우 쉽게 수행 할 수 있으므로 인코딩해야합니다.

$ strings libsecretlib.so | grep My
  My_S3cr3t_P@$$W0rD

3
그리고 상기 서버의 자격 증명을 어디에 저장하고 있습니까?
ZX9 December
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.