Thực hành tốt nhất để lưu trữ và bảo vệ các khóa API riêng tư trong các ứng dụng [đã đóng]


373

Hầu hết các nhà phát triển ứng dụng sẽ tích hợp một số thư viện của bên thứ ba vào ứng dụng của họ. Nếu đó là để truy cập một dịch vụ, chẳng hạn như Dropbox hoặc YouTube hoặc để ghi nhật ký sự cố. Số lượng thư viện và dịch vụ của bên thứ ba rất đáng kinh ngạc. Hầu hết các thư viện và dịch vụ đó được tích hợp bằng cách xác thực bằng cách nào đó với dịch vụ, hầu hết thời gian, điều này xảy ra thông qua khóa API. Vì mục đích bảo mật, các dịch vụ thường tạo ra một khóa công khai và riêng tư, thường được gọi là khóa bí mật. Thật không may, để kết nối với các dịch vụ, khóa riêng này phải được sử dụng để xác thực và do đó, có lẽ là một phần của ứng dụng. Không cần phải nói, rằng điều này phải đối mặt với vấn đề an ninh rất lớn. Khóa API công khai và riêng tư có thể được trích xuất từ ​​APK trong vài phút và có thể dễ dàng được tự động hóa.

Giả sử tôi có một cái gì đó tương tự như thế này, làm thế nào tôi có thể bảo vệ khóa bí mật:

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

}

Theo bạn, cách tốt nhất và an toàn nhất để lưu trữ khóa riêng là gì? Obfuscation, mã hóa, bạn nghĩ gì?



tôi đã lưu trữ hình ảnh / png và nhận khóa thông qua png với tư cách là BufferReader
Sumit

Tôi nghĩ rằng đây là một mối quan tâm hợp lệ và đã đăng một vấn đề tương tự trên trang github của Firebase Android: github.com/firebase/firebase-android-sdk/issues/1583 . Hãy xem nếu điều này được xử lý.
grebulon

Câu trả lời:


348
  1. Như vậy, ứng dụng đã biên dịch của bạn chứa các chuỗi khóa, nhưng cũng có tên không đổi APP_KEY và APP_SECRET. Trích xuất các khóa từ mã tự viết tài liệu như vậy là không đáng kể, ví dụ với công cụ Android tiêu chuẩn dx.

  2. Bạn có thể áp dụng ProGuard. Nó sẽ để lại các chuỗi khóa không bị ảnh hưởng, nhưng nó sẽ loại bỏ các tên không đổi. Nó cũng sẽ đổi tên các lớp và phương thức với các tên ngắn, vô nghĩa, nếu có thể. Việc trích xuất các khóa sau đó sẽ mất thêm thời gian để tìm ra chuỗi nào phục vụ mục đích nào.

    Lưu ý rằng việc thiết lập ProGuard không nên khó khăn như bạn sợ. Để bắt đầu, bạn chỉ cần kích hoạt ProGuard, như được ghi lại trong project.properations. Nếu có bất kỳ vấn đề nào với các thư viện của bên thứ ba, bạn có thể cần phải loại bỏ một số cảnh báo và / hoặc ngăn không cho chúng bị xáo trộn, trong proguard-project.txt. Ví dụ:

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

    Đây là một cách tiếp cận vũ phu; bạn có thể tinh chỉnh cấu hình như vậy một khi ứng dụng được xử lý hoạt động.

  3. Bạn có thể làm xáo trộn các chuỗi theo cách thủ công trong mã của mình, ví dụ với mã hóa Base64 hoặc tốt nhất là với một cái gì đó phức tạp hơn; thậm chí có thể mã nguồn. Sau đó, một hacker sẽ phải thiết kế đảo ngược tĩnh mã hóa mã hóa của bạn hoặc tự động chặn mã hóa ở vị trí thích hợp.

  4. Bạn có thể áp dụng một obfuscator thương mại, như anh chị em chuyên biệt của ProGuard, DexGuard . Nó cũng có thể mã hóa / làm xáo trộn các chuỗi và các lớp cho bạn. Trích xuất các khóa sau đó thậm chí còn mất nhiều thời gian và chuyên môn hơn.

  5. Bạn có thể chạy các phần của ứng dụng trên máy chủ của riêng bạn. Nếu bạn có thể giữ chìa khóa ở đó, chúng an toàn.

Cuối cùng, đó là một sự đánh đổi kinh tế mà bạn phải thực hiện: các khóa quan trọng như thế nào, bạn có thể mua bao nhiêu thời gian hoặc phần mềm, các hacker quan tâm đến các khóa như thế nào, họ sẽ muốn bao nhiêu thời gian chi tiêu, đáng giá bao nhiêu là một sự chậm trễ trước khi các khóa bị hack, theo quy mô nào thì bất kỳ tin tặc thành công nào sẽ phân phối các khóa, v.v. Những mẩu thông tin nhỏ như khóa khó bảo vệ hơn toàn bộ ứng dụng. Về mặt bản chất, không có gì ở phía khách hàng là không thể phá vỡ, nhưng bạn chắc chắn có thể nâng thanh.

(Tôi là nhà phát triển của ProGuard và DexGuard)


2
@EricLafortune nó không tạo ra sự khác biệt nếu chuỗi khóa riêng được lưu trữ trong lớp Java so với XML tài nguyên chuỗi?
Alan

1
@EricLafortune Bây giờ có thể sử dụng hệ thống Kho khóa của Android để lưu trữ khóa một cách an toàn không? ( developer.android.com/training/articles/keystore.html )
David Thomas

1
@DavidThomas: Bạn đã thử sử dụng kho khóa. Tôi muốn làm xáo trộn khóa API được viết bằng lớp Java. Vui lòng trả lời
Sagar Trehan 14/07/2016

1
Android KeyStore có hữu ích cho việc này không? ( developer.android.com/training/articles/ cường )
Weishi Zeng

1
Tôi không hiểu # 5. Nó không có vấn đề chính xác như vấn đề ban đầu sao?
pete

80

Vài ý tưởng, theo tôi chỉ có ý tưởng đầu tiên đưa ra một số đảm bảo:

  1. Giữ bí mật của bạn trên một số máy chủ trên internet, và khi cần chỉ cần lấy chúng và sử dụng. Nếu người dùng sắp sử dụng dropbox thì không có gì ngăn bạn đưa ra yêu cầu đến trang web của bạn và lấy khóa bí mật của bạn.

  2. Đặt bí mật của bạn trong mã jni, thêm một số mã biến để làm cho thư viện của bạn lớn hơn và khó dịch hơn. Bạn cũng có thể chia chuỗi khóa thành nhiều phần và giữ chúng ở nhiều nơi.

  3. sử dụng obfuscator, cũng đặt mã băm bí mật và sau đó không xóa nó khi cần sử dụng.

  4. Đặt khóa bí mật của bạn làm pixel cuối cùng của một trong những hình ảnh của bạn trong tài sản. Sau đó, khi cần đọc nó trong mã của bạn. Làm xáo trộn mã của bạn sẽ giúp ẩn mã sẽ đọc nó.

Nếu bạn muốn có một cái nhìn nhanh chóng về việc đọc mã apk của bạn dễ dàng như thế nào thì hãy lấy APKAnalyser:

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


46
nếu người dùng có thể dịch ngược ứng dụng mặc dù họ có thể xác định yêu cầu được gửi đến máy chủ của riêng bạn và chỉ cần thực hiện điều đó để lấy bí mật. Không có viên đạn bạc nào ở đây nhưng hãy thực hiện vài bước và tôi cá là bạn sẽ ổn thôi! Nếu ứng dụng của bạn là siêu phổ biến mặc dù có thể không .. Ý tưởng tuyệt vời!
Matt Wolfe

3
yeah, số 1 không đảm bảo.
marcinj

42
Tôi thực sự thích ý tưởng ẩn chìa khóa bên trong hình ảnh. +1
Igor ordaš

1
@ MarcinJędrzejewski Bạn có muốn giải thích thêm (tốt nhất là lấy mẫu hoặc mã snipped) về giải pháp không? Cảm ơn bạn.
Dr.jacky

2
@ Mr.Hyde cái này được gọi là steganography, cách của nó quá phức tạp để đưa ra một mã mẫu ở đây, bạn có thể tìm thấy các ví dụ trên google. Tôi đã tìm thấy một ở đây: dreamincode.net/forums/topic/27950-steganography . Ý tưởng là tuyệt vời nhưng vì mã apk có thể được dịch ngược nên nó làm hỏng vẻ đẹp của nó.
marcinj

33

Một cách tiếp cận khác là không có bí mật trên thiết bị ngay từ đầu! Xem Kỹ thuật bảo mật API di động (đặc biệt là phần 3).

Sử dụng truyền thống tôn vinh thời gian được tôn vinh, chia sẻ bí mật giữa điểm cuối API của bạn và dịch vụ xác thực ứng dụng.

Khi khách hàng của bạn muốn thực hiện cuộc gọi API , nó sẽ yêu cầu dịch vụ xác thực ứng dụng xác thực nó (sử dụng các kỹ thuật chứng thực từ xa mạnh mẽ) và nó nhận được mã thông báo giới hạn thời gian (thường là JWT ) được ký bởi bí mật.

Mã thông báo được gửi với mỗi lệnh gọi API trong đó điểm cuối có thể xác minh chữ ký của nó trước khi thực hiện yêu cầu.

Bí mật thực sự không bao giờ có trên thiết bị; trong thực tế, ứng dụng không bao giờ có bất kỳ ý tưởng nào nếu nó hợp lệ hay không, nó sẽ yêu cầu xác thực và chuyển mã thông báo kết quả. Là một lợi ích tốt từ sự gián tiếp, nếu bạn muốn thay đổi bí mật, bạn có thể làm như vậy mà không yêu cầu người dùng cập nhật các ứng dụng đã cài đặt của họ.

Vì vậy, nếu bạn muốn bảo vệ bí mật của mình, không có nó trong ứng dụng của bạn ngay từ đầu là một cách khá tốt để đi.


5
Đây phải là câu trả lời được chấp nhận.
ortonomy

3
Vấn đề vẫn tồn tại khi bạn muốn truy cập dịch vụ xác thực. Nó sẽ cung cấp cho bạn một id khách hàng và bí mật khách hàng. Chúng ta nên cứu họ ở đâu?
Ashi

không giải quyết apis riêng nơi bạn cần xác thực với api của mình trước để sử dụng nó. nơi nào bạn có được thông tin đăng nhập cho tất cả người dùng ứng dụng?
Kibotu

25

Cách không bảo đảm cũ:

Thực hiện theo 3 bước đơn giản để bảo mật API / Khóa bí mật ( Câu trả lời cũ )

Chúng tôi có thể sử dụng Gradle để bảo mật khóa API hoặc Khóa bí mật.

1. gradle.properies (Thuộc tính dự án): Tạo biến bằng khóa.

GoolgeAPIKey = "Your API/Secret Key"

2. build.gradle (Module: app): Đặt biến trong build.gradle để truy cập nó trong hoạt động hoặc đoạn. Thêm mã dưới đây vào buildTypes {}.

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

3. Truy cập nó trong Activity / Fragment bởi ứng dụng BuildConfig:

BuildConfig.GoogleSecAPIKEY

Cập nhật:

Giải pháp trên hữu ích trong dự án nguồn mở để cam kết với Git. (Cảm ơn David Rawson và riyaz-ali vì bình luận của bạn).

Theo nhận xét của Matthew và Pablo Cegarra, cách trên không an toàn và Decompiler sẽ cho phép ai đó xem BuildConfig bằng các khóa bí mật của chúng tôi.

Giải pháp :

Chúng tôi có thể sử dụng NDK để bảo mật API khóa. Chúng ta có thể lưu trữ các khóa trong lớp C / C ++ bản địa và truy cập chúng trong các lớp Java của chúng ta.

Vui lòng theo dõi blog này để bảo mật các khóa API bằng NDK.

Hướng dẫn về cách lưu trữ mã thông báo an toàn trong Android


4
lưu trữ một khóa trong tập tin gradle là an toàn?
Google

4
@Google gradle.propertieskhông nên đăng ký vào Git vì vậy đây là cách giữ bí mật khỏi mã nguồn đã cam kết, ít nhất
David Rawson

4
Điều này không ngăn khóa API bị bó vào kết quả apk(nó sẽ được thêm vào BuildConfigtệp được tạo ), mặc dù đây chắc chắn là một ý tưởng tốt để quản lý các khóa API khác nhau (ví dụ: trong một dự án nguồn mở)
riyaz-ali

5
Sử dụng Trình dịch ngược Java sẽ cho phép ai đó xem tệp BuildConfig và "GoogleSecAPIKEY"
Matthew

3
BuildConfig.javaTập tin của bạn sẽ có khóa ở dạng văn bản thuần túy. Điều này không tốt hơn những gì OP đang làm.
iceman

16

Khóa bí mật ứng dụng nên được giữ riêng tư - nhưng khi phát hành ứng dụng, chúng có thể bị đảo ngược bởi một số kẻ.

Đối với những kẻ đó, nó sẽ không ẩn, khóa ProGuardmã. Nó là một bộ tái cấu trúc và một số obfuscators trả phí đang chèn một vài toán tử bitwise để lấy lại jk433g34hg3 String. Bạn có thể thực hiện hack từ 5 đến 15 phút nếu bạn làm việc 3 ngày :)

Cách tốt nhất là giữ nó như nó là, imho.

Ngay cả khi bạn lưu trữ ở phía máy chủ (PC), khóa vẫn có thể bị hack và in ra. Có lẽ điều này mất nhiều thời gian nhất? Dù sao đó là vấn đề của vài phút hoặc vài giờ trong trường hợp tốt nhất.

Một người dùng bình thường sẽ không dịch ngược mã của bạn.


1
Chà - không phải câu trả lời mà tôi hy vọng nhận được =) ... Tôi nghĩ bạn có thể đạt được sự bảo mật tuyệt vời :(
cơ bản

Xin lỗi, nó không phải như bạn muốn một giải pháp brillinant, cực kỳ an toàn, nhưng đối với những người có thể sử dụng trình biên dịch, trình dịch ngược không có mã java an toàn: thậm chí có thể xem mã gốc bằng trình xem hexa và giải mã. Ít nhất là đáng để thử ...

1
Proguard sẽ không làm xáo trộn khóa thực tế mặc dù ..? Điều tốt nhất để làm là một số thói quen encript / decript đơn giản, mà obfuscate sẽ ẩn.
Doomsknight

3
đó là "hiển thị" thói quen giải mã, dễ dàng thực hiện ngược lại và bạn có chuỗi gốc

14

Một giải pháp khả thi là mã hóa dữ liệu trong ứng dụng của bạn và sử dụng giải mã khi chạy (khi bạn muốn sử dụng dữ liệu đó). Tôi cũng khuyên bạn nên sử dụng progaurd để làm cho nó khó đọc và hiểu mã nguồn được dịch ngược của ứng dụng của bạn. ví dụ: tôi đặt một khóa được mã hóa trong ứng dụng và sau đó sử dụng phương thức giải mã trong ứng dụng của mình để giải mã các khóa bí mật của mình khi chạy:

// "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=="));
}

Mã nguồn được dịch ngược của ứng dụng được bảo vệ là đây:

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

Ít nhất nó đủ phức tạp đối với tôi. đây là cách tôi làm khi không có lựa chọn nào khác ngoài việc lưu trữ một giá trị trong ứng dụng của mình. Tất nhiên tất cả chúng ta đều biết Đó không phải là cách tốt nhất nhưng nó hiệu quả với tôi.

/**
 * @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";
}

Phiên bản dịch ngược:

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

và bạn có thể tìm thấy rất nhiều lớp mã hóa với một chút tìm kiếm trong google.


13

Thêm vào giải pháp @Manohar Reddy, cơ sở dữ liệu firebase hoặc firebase RemoteConfig (với giá trị mặc định Null) có thể được sử dụng:

  1. Mật mã khóa của bạn
  2. Lưu trữ nó trong cơ sở dữ liệu firebase
  3. Nhận nó trong khi khởi động ứng dụng hoặc bất cứ khi nào cần thiết
  4. giải mã các khóa và sử dụng nó

Điều gì khác biệt trong giải pháp này?

  • không có tín dụng cho căn cứ hỏa lực
  • Quyền truy cập firebase được bảo vệ nên chỉ ứng dụng có chứng chỉ đã ký mới có đặc quyền thực hiện cuộc gọi API
  • mã hóa / giải mã để ngăn chặn sự can thiệp của người trung gian. Tuy nhiên, cuộc gọi đã https đến căn cứ hỏa lực

với tất cả sự tôn trọng với giải pháp này, chúng tôi vẫn là hình vuông đầu tiên. Thay vì sử dụng thông tin đăng nhập, bạn đề nghị sử dụng chứng chỉ. Bất cứ ai có khả năng đánh cắp thông tin đăng nhập của bạn đều có khả năng đánh cắp chứng chỉ đã ký của bạn.
Ashi

Mặc dù vậy, với một lợi thế, với giải pháp được đề xuất, chúng tôi đang thêm một sự phức tạp nữa trước mặt hacker.
Ashi

11

Ví dụ này có một số khía cạnh khác nhau với nó. Tôi sẽ đề cập đến một vài điểm mà tôi không nghĩ rằng đã được đề cập rõ ràng ở nơi khác.

Bảo vệ bí mật trong quá cảnh

Điều đầu tiên cần lưu ý là việc truy cập API dropbox bằng cơ chế xác thực ứng dụng của họ yêu cầu bạn truyền khóa và bí mật của mình. Kết nối là HTTPS, có nghĩa là bạn không thể chặn lưu lượng mà không biết chứng chỉ TLS. Điều này là để ngăn chặn một người chặn và đọc các gói trên hành trình của họ từ thiết bị di động đến máy chủ. Đối với người dùng bình thường, đó là một cách thực sự tốt để đảm bảo sự riêng tư của lưu lượng truy cập của họ.

Những gì nó không tốt, là ngăn chặn một kẻ độc hại tải xuống ứng dụng và kiểm tra lưu lượng. Thật sự dễ dàng khi sử dụng proxy trung gian cho tất cả lưu lượng truy cập vào và ra khỏi thiết bị di động. Nó sẽ không yêu cầu tháo gỡ hoặc thiết kế ngược mã để trích xuất khóa ứng dụng và bí mật trong trường hợp này do bản chất của API Dropbox.

Bạn có thể thực hiện ghim kiểm tra xem chứng chỉ TLS bạn nhận được từ máy chủ có phải là chứng chỉ bạn mong đợi không. Điều này thêm một kiểm tra cho khách hàng và làm cho việc chặn lưu lượng truy cập khó khăn hơn. Điều này sẽ khiến việc kiểm tra lưu lượng trong chuyến bay trở nên khó khăn hơn, nhưng kiểm tra ghim xảy ra trong máy khách, do đó có khả năng vẫn có thể vô hiệu hóa kiểm tra ghim. Nó làm cho nó khó hơn mặc dù.

Bảo vệ bí mật khi nghỉ ngơi

Bước đầu tiên, sử dụng một cái gì đó như proguard sẽ giúp làm cho nó ít rõ ràng hơn khi có bất kỳ bí mật nào được giữ. Bạn cũng có thể sử dụng NDK để lưu trữ khóa và bí mật và gửi yêu cầu trực tiếp, điều này sẽ giúp giảm đáng kể số lượng người có kỹ năng phù hợp để trích xuất thông tin. Việc che giấu thêm có thể đạt được bằng cách không lưu trữ các giá trị trực tiếp trong bộ nhớ trong bất kỳ khoảng thời gian nào, bạn có thể mã hóa chúng và giải mã chúng ngay trước khi sử dụng theo đề xuất của câu trả lời khác.

Tùy chọn nâng cao hơn

Nếu bây giờ bạn đang hoang tưởng về việc đặt bí mật ở bất cứ đâu trong ứng dụng của mình và bạn có thời gian và tiền bạc để đầu tư vào các giải pháp toàn diện hơn, thì bạn có thể xem xét việc lưu trữ thông tin đăng nhập trên máy chủ của mình (giả sử bạn có bất kỳ). Điều này sẽ làm tăng độ trễ của bất kỳ cuộc gọi nào tới API, vì nó sẽ phải liên lạc qua máy chủ của bạn và có thể làm tăng chi phí vận hành dịch vụ của bạn do tăng thông lượng dữ liệu.

Sau đó, bạn phải quyết định cách tốt nhất để liên lạc với máy chủ của mình để đảm bảo chúng được bảo vệ. Điều này rất quan trọng để ngăn chặn tất cả các vấn đề tương tự xuất hiện trở lại với API nội bộ của bạn. Nguyên tắc tốt nhất tôi có thể đưa ra là không truyền trực tiếp bất kỳ bí mật nào vì mối đe dọa trung gian. Thay vào đó, bạn có thể ký lưu lượng bằng cách sử dụng bí mật của mình và xác minh tính toàn vẹn của bất kỳ yêu cầu nào đến máy chủ của bạn. Một cách tiêu chuẩn để làm điều này là tính toán một HMAC của thông điệp được khóa trong một bí mật. Tôi làm việc tại một công ty có một sản phẩm bảo mật cũng hoạt động trong lĩnh vực này, đó là lý do tại sao loại công cụ này làm tôi quan tâm. Trong thực tế, đây là một bài viết blog từ một trong những đồng nghiệp của tôi đi qua hầu hết điều này.

Tôi nên làm bao nhiêu?

Với bất kỳ lời khuyên bảo mật nào như thế này, bạn cần đưa ra quyết định chi phí / lợi ích về mức độ khó khăn của bạn khi khiến ai đó đột nhập. Nếu bạn là ngân hàng bảo vệ hàng triệu khách hàng, ngân sách của bạn hoàn toàn khác với ai đó hỗ trợ ứng dụng trong họ thời gian rảnh. Hầu như không thể ngăn ai đó phá vỡ an ninh của bạn, nhưng trong thực tế, rất ít người cần tất cả chuông và còi và với một số biện pháp phòng ngừa cơ bản, bạn có thể đi được một chặng đường dài.


1
Bạn chỉ cần sao chép và dán cái này từ đây: hackernoon.com/mobile-api-security-techniques-682a5da4fe10 mà không cần thừa nhận nguồn.
ortonomy

1
@ortonomy Tôi đồng ý rằng anh ấy nên trích dẫn bài báo mà bạn đã liên kết, nhưng anh ấy có thể đã quên nó vì cả hai đều làm việc ở cùng một nơi ...
Exadra37

2
Ngoài ra bài viết của Skip và bài đăng trên blog mà họ dựa trên đã xuất hiện một tuần sau câu trả lời của tôi.
ThePragmatist

8

Giải pháp an toàn nhất là giữ các khóa của bạn trên máy chủ và định tuyến tất cả các yêu cầu cần khóa đó thông qua máy chủ của bạn. Bằng cách đó, khóa không bao giờ rời khỏi máy chủ của bạn, miễn là máy chủ của bạn được bảo mật thì khóa của bạn cũng vậy. Tất nhiên có một chi phí hiệu suất với giải pháp này.


32
Vấn đề là - để đến được máy chủ chứa tất cả các bí mật tôi nên sử dụng một Khóa bí mật khác - tôi tự hỏi tôi sẽ giữ nó ở đâu? ;) Điều tôi đang cố gắng nói là - Đây cũng không phải là giải pháp tốt nhất (đừng nghĩ có một giải pháp lý tưởng ở đây)
Sao Thủy

Điều đó không đúng, máy chủ của bạn hoàn toàn nằm trong tầm kiểm soát của bạn. Những gì nó đòi hỏi hoàn toàn phụ thuộc vào bạn.
Bernard Igiri

5
Bạn có thể giải thích ở đây làm thế nào khách hàng có thể mã hóa dữ liệu anh ta muốn gửi đến máy chủ, trong khi các khóa nằm ở phía máy chủ không? và nếu câu trả lời của bạn sẽ là - Máy chủ sẽ gửi khóa cho khách hàng - Vì vậy, điều đó cũng phải được bảo mật! Vì vậy, một lần nữa không có giải pháp kỳ diệu! bạn không thấy sao?!
Sao Thủy

2
@BernardIgiri và sau đó một lần nữa chúng ta quay lại quảng trường 1. Giả sử, điện thoại tạo một đăng nhập ngẫu nhiên và máy chủ chấp nhận điều đó và gửi mã pin (Đây là máy chủ riêng mà chúng ta đang nói). Sau đó, người tháo rời ứng dụng của bạn thấy rằng tất cả những gì cần thiết để truy cập máy chủ riêng của bạn chỉ là một số đăng nhập ngẫu nhiên mà anh ta có thể tự tạo. Hãy cho tôi biết điều gì ngăn anh ta tạo một cái và truy cập máy chủ của bạn? Trên thực tế, sự khác biệt giữa giải pháp của bạn và thực sự lưu trữ khóa đăng nhập hoặc khóa api vào máy chủ chính (có thông tin đăng nhập mà chúng tôi muốn lưu trữ trong máy chủ riêng của chúng tôi)
Ken

3
@ken Số ngẫu nhiên được xác thực dựa trên số điện thoại và quyền truy cập vật lý vào tin nhắn văn bản của nó. Nếu ai đó lừa dối bạn, bạn có thông tin của họ. Nếu điều đó không đủ tốt, buộc họ phải tạo một tài khoản và mật khẩu người dùng đầy đủ. Nếu điều đó không đủ tốt, hãy lấy thẻ tín dụng. Nếu điều đó không đủ tốt để họ gọi đến. Nếu điều đó không đủ tốt để gặp họ trực tiếp. Bạn muốn an toàn / bất tiện như thế nào?
Bernard Igiri

7

Giữ bí mật firebase databasevà nhận được từ nó khi ứng dụng bắt đầu, Nó tốt hơn nhiều so với việc gọi một dịch vụ web.


13
Nhưng những gì về thông tin cho căn cứ hỏa lực?
the_joric

2
Thật không may, cơ sở dữ liệu Firebase không hoạt động ở Trung Quốc.
Konjengbam

9
không có ý nghĩa gì, những kẻ tấn công có thể thấy bạn chi tiết về căn cứ hỏa lực từ mã dịch ngược và nhận bất kỳ dữ liệu nào từ cơ sở dữ liệu của bạn
user924

3
Tôi nghĩ rằng đây là giải pháp tốt nhất vì Ứng dụng firebase sử dụng SHA1 để cho phép truy cập vào máy chủ. Dịch ngược mã sẽ không giúp thực hiện cuộc gọi đến firebase vì ứng dụng mới của hacker nên sử dụng tem ứng dụng chính xác để truy cập firebase. Ngoài ra, khóa được lưu trữ phải được mã hóa trước khi lưu trữ trong DB căn cứ hỏa lực và được giải mã một lần nhận được để tránh sự can thiệp của người trung gian.
Ayman Al-Absi

Khi bạn nhận được bí mật từ cơ sở dữ liệu firebase thông qua mạng, làm thế nào an toàn hơn so với nhận cùng một bí mật từ một dịch vụ web khác thông qua kênh (https) an toàn? Bạn có thể giải thích?
Csaba Toth

6

Bất cứ điều gì bạn làm để bảo mật các khóa bí mật của bạn sẽ không phải là một giải pháp thực sự. Nếu nhà phát triển có thể dịch ngược ứng dụng thì không có cách nào để bảo mật khóa, việc ẩn khóa chỉ là bảo mật bằng cách che khuất và mã obfuscation cũng vậy. Vấn đề với việc bảo mật một khóa bí mật là để bảo mật nó, bạn phải sử dụng một khóa khác và khóa đó cũng cần phải được bảo mật. Hãy nghĩ về một chìa khóa được giấu trong một hộp được khóa bằng một chìa khóa. Bạn đặt một hộp bên trong một căn phòng và khóa phòng. Bạn còn lại một chìa khóa khác để bảo mật. Và khóa đó vẫn sẽ được mã hóa cứng trong ứng dụng của bạn.

Vì vậy, trừ khi người dùng nhập mã PIN hoặc cụm từ, không có cách nào để ẩn khóa. Nhưng để làm được điều đó, bạn sẽ phải có một kế hoạch quản lý mã PIN xảy ra ngoài băng, nghĩa là thông qua một kênh khác. Chắc chắn không thực tế để bảo mật các khóa cho các dịch vụ như Google API.


5

Lứa tuổi bài cũ, nhưng vẫn đủ tốt. Tôi nghĩ việc giấu nó trong một thư viện .so sẽ rất tuyệt, sử dụng NDK và C ++. Các tập tin .so có thể được xem trong trình soạn thảo hex, nhưng chúc may mắn dịch ngược rằng: P


9
Người dùng có thể dễ dàng thực hiện các cuộc gọi chức năng đến thư viện chia sẻ và nhận bất cứ điều gì đang ẩn ở đó. Không cần phải giải mã nó.
david72

5
Theo android Tác giả.com , không có cách nào an toàn để làm điều đó trong Android vào lúc này.
david72

1
@AhmedAwad Đừng hiểu tại sao điều này lại có 3 upvote. bất kỳ ai cũng có thể dễ dàng dịch ngược ứng dụng và xem điểm truy cập ndk đang được gọi như thế nào: /
Johny19

1
Câu trả lời này gần như là một trong những lựa chọn tốt nhất, nhưng tác giả nên đề cập rằng điều rất quan trọng là bạn nên bao gồm một cuộc gọi (bên trong thư viện NDK của bạn) để xem tổng kiểm tra có khớp với APK của bạn không vì có ai đó có thể gọi thư viện NDK của bạn bên ngoài ứng dụng của bạn
Stoycho Andreev

@Sniper đó sẽ là tuyệt vời, ngoại trừ nó có một vấn đề lớn. Làm thế nào để bạn biết tập tin nào đang "gọi" phương thức gốc? Nếu bạn khó mã hóa tên apk để kiểm tra, thật tuyệt, nhưng nếu tôi tạo apk "hack" của mình cùng thư mục với apk "tốt" thì sao? Nó sẽ kiểm tra xem apk "tốt" có tổng kiểm tra tốt hay không và nó sẽ cho phép tôi thực hiện phương thức gốc đó. Trừ khi có cách để biết tệp người gọi từ phía JNI / C ++, thì đó là vô nghĩa như các tùy chọn khác.
SocketByte

5

Cách thực sự duy nhất để giữ riêng tư này là giữ chúng trên máy chủ của bạn và yêu cầu ứng dụng gửi bất cứ thứ gì đến máy chủ và máy chủ tương tác với Dropbox. Bằng cách đó, bạn KHÔNG BAO GIỜ phân phối khóa riêng của mình ở bất kỳ định dạng nào.


11
Nhưng làm thế nào để bạn ngăn chặn phần còn lại của thế giới gọi máy chủ?
dùng2966445

Nếu theo "máy chủ", bạn có nghĩa là máy chủ web của bạn có thông tin đăng nhập - bạn có thể sử dụng bất kỳ phương pháp nào bạn muốn. xác thực đơn giản với tên người dùng / mật khẩu, oauth, thư mục hoạt động, vv vv Thực sự phụ thuộc vào ứng dụng của bạn.
Nick

Có thể tôi đang thiếu một cái gì đó, nhưng điều này vẫn không yêu cầu lưu trữ thông tin đăng nhập trong ứng dụng?
dùng2966445

3
Đúng, nhưng bạn nói ứng dụng sẽ xác thực với máy chủ trước. Điều này không có nghĩa là lưu trữ một bộ thông tin đăng nhập khác trong ứng dụng? Tôi hiểu rằng máy chủ sẽ xử lý các cuộc gọi dropbox thực tế.
dùng2966445

4
Vâng, nó có thể có nghĩa là, nhưng nó là một ủy quyền hoàn toàn riêng biệt. Nhưng bạn không cần phải làm vậy. Usecase mà tôi đang nói đến là người dùng ứng dụng của bạn sẽ đăng nhập vào ứng dụng của bạn, giả sử sử dụng facebook hoặc twitter. Bạn không lưu trữ thông tin đăng nhập của họ trong ứng dụng của bạn, thậm chí bạn không biết họ. Quá trình ủy quyền đó cho phép họ truy cập vào máy chủ api của bạn, nơi có thông tin đăng nhập vào dropbox, nhưng không có ứng dụng hoặc người dùng nào có quyền truy cập trực tiếp vào họ.
Nick

0

Dựa trên kinh nghiệm cay đắng và sau khi tham khảo ý kiến ​​chuyên gia IDA-Pro, giải pháp tốt nhất là chuyển một phần quan trọng của mã vào DLL / SharedObject, sau đó tìm nạp nó từ máy chủ và tải khi chạy.

Dữ liệu nhạy cảm phải được mã hóa vì nó rất dễ thực hiện như thế này:

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

3
Và bạn đang lưu trữ thông tin đăng nhập cho máy chủ nói ở đâu?
ZX9
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.