Làm cách nào để lưu trữ an toàn mã thông báo truy cập và bí mật trong Android?


123

Tôi sẽ sử dụng oAuth để tìm nạp thư và danh bạ từ google. Tôi không muốn yêu cầu người dùng mỗi lần đăng nhập để lấy mã thông báo truy cập và bí mật. Từ những gì tôi hiểu, tôi cần lưu trữ chúng với ứng dụng của mình trong cơ sở dữ liệu hoặc SharedPreferences. Nhưng tôi hơi lo lắng về khía cạnh bảo mật với điều đó. Tôi đọc rằng bạn có thể mã hóa và giải mã mã thông báo nhưng kẻ tấn công rất dễ dàng chỉ cần dịch ngược gói ứng dụng và lớp của bạn và lấy khóa mã hóa.
Phương pháp tốt nhất để lưu trữ an toàn các mã thông báo này trong Android là gì?


1
Làm cách nào để lưu trữ khóa và bí mật của người tiêu dùng (khóa cứng không được bảo mật)? tôi cần họ yêu cầu accesstoken và bí mật .. làm thế nào để các ứng dụng hiện có khác sử dụng oauth làm điều đó? hmm cuối cùng với oauth, bạn cần quan tâm đến nhiều vấn đề bảo mật hơn cho tôi .... tôi cần giữ mã thông báo / bí mật của người tiêu dùng một cách an toàn, đồng thời cũng là lời nói và bí mật .... cuối cùng sẽ không đơn giản hơn để chỉ lưu trữ tên người dùng / mật khẩu của người dùng được mã hóa? ... Cuối cùng, không phải cái sau tốt hơn sao? Tôi chỉ vẫn không thể xem như thế nào oauth là tốt hơn ...
yeahman

bạn có thể cho tôi biết..tệp nào lưu trữ mã thông báo truy cập ?? Tôi mới vào Android và tôi đã cố gắng chạy mẫu Thêm app.But Tôi không tìm thấy bất cứ nơi nào này [phương pháp GoogleAuthUtil.getToken ().]
Abhishek Kaushik

Câu trả lời:


117

Lưu trữ chúng dưới dạng tùy chọn được chia sẻ . Theo mặc định, chúng là riêng tư và các ứng dụng khác không thể truy cập chúng. Trên thiết bị đã root, nếu người dùng cho phép rõ ràng quyền truy cập vào một số ứng dụng đang cố đọc chúng, ứng dụng đó có thể sử dụng chúng, nhưng bạn không thể bảo vệ khỏi điều đó. Đối với mã hóa, bạn phải yêu cầu người dùng nhập cụm mật khẩu giải mã mọi lúc (do đó đánh bại mục đích lưu thông tin đăng nhập vào bộ nhớ đệm) hoặc lưu khóa vào một tệp và bạn sẽ gặp phải vấn đề tương tự.

Có một số lợi ích của việc lưu trữ mã thông báo thay vì mật khẩu tên người dùng thực tế:

  • Các ứng dụng của bên thứ ba không cần biết mật khẩu và người dùng có thể chắc chắn rằng họ chỉ gửi mật khẩu đó đến trang web gốc (Facebook, Twitter, Gmail, v.v.)
  • Ngay cả khi ai đó đánh cắp mã thông báo, họ sẽ không thấy mật khẩu (người dùng có thể đang sử dụng trên các trang web khác)
  • Token thường có thời gian tồn tại và hết hạn sau một thời gian nhất định
  • Token có thể bị thu hồi nếu bạn nghi ngờ chúng đã bị xâm phạm

1
thx cho câu trả lời! nhưng làm thế nào tôi có thể biết nếu khóa khách hàng của tôi đã bị xâm phạm? lol sẽ rất khó để nói .. ok về việc lưu trữ mã thông báo truy cập và bí mật, ok tôi lưu chúng trong các tài liệu tham khảo được chia sẻ và mã hóa chúng nhưng còn khóa và bí mật của người tiêu dùng thì sao? Tôi không thể lưu trữ chúng trong các tài liệu tham khảo được chia sẻ (tôi sẽ cần phải viết rõ ràng khóa người dùng và bí mật trong mã để lưu nó trong tham chiếu chia sẻ ngay từ đầu) .. không biết bạn có hiểu ý tôi không.
yeahman

2
Bạn phải đưa ứng dụng vào ứng dụng theo một cách (hơi khó hiểu), vì chúng sẽ không hiển thị ngay lập tức sau khi dịch ngược hoặc sử dụng ứng dụng web proxy xác thực của riêng bạn có khóa và bí mật. Đưa chúng vào ứng dụng rõ ràng là dễ dàng hơn và nếu cho rằng nguy cơ ai đó cố gắng bẻ khóa ứng dụng của bạn là đủ thấp, hãy thực hiện cách tiếp cận đó. BTW, các điểm trên là mật khẩu người dùng. Nếu bạn phát hiện ra khóa / bí mật người tiêu dùng của mình đã bị xâm phạm, bạn cũng có thể thu hồi chúng (tất nhiên, điều đó sẽ phá vỡ ứng dụng của bạn).
Nikolay Elenkov

1
@NikolayElenkov: Bạn đã viết 'Đối với mã hóa, bạn phải yêu cầu người dùng nhập cụm mật khẩu giải mã mọi lúc (do đó đánh bại mục đích lưu thông tin đăng nhập vào bộ nhớ đệm) hoặc lưu khóa vào tệp và bạn cũng gặp phải vấn đề tương tự.' . Điều gì sẽ xảy ra nếu những kẻ bẻ khóa đảo ngược ứng dụng của bạn để hiểu rõ cách thức hoạt động của mã hóa? Phòng thủ của bạn có thể bị phá vỡ. Có phải là phương pháp hay nhất để lưu trữ thông tin như vậy (mã thông báo, mã hóa ...) bằng mã gốc không?
anhldbk

1
Nếu dữ liệu ứng dụng bị xóa, thì mã làm mới sẽ bị mất, đây có thể không phải là điều người dùng mong muốn.
rds

1
Đây không phải là cách tốt nhất để lưu trữ mã thông báo bây giờ-một-ngày!
Rahul Rastogi

19

Bạn có thể lưu trữ chúng trong AccountManager . Đó được coi là phương pháp tốt nhất theo những người này.

nhập mô tả hình ảnh ở đây

Đây là định nghĩa chính thức:

Lớp này cung cấp quyền truy cập vào sổ đăng ký tập trung các tài khoản trực tuyến của người dùng. Người dùng nhập thông tin đăng nhập (tên người dùng và mật khẩu) một lần cho mỗi tài khoản, cấp cho ứng dụng quyền truy cập vào tài nguyên trực tuyến với sự chấp thuận "một lần nhấp".

Để có hướng dẫn chi tiết về cách sử dụng AccountManager:

Tuy nhiên, cuối cùng AccountManager chỉ lưu trữ mã thông báo của bạn dưới dạng văn bản thuần túy. Vì vậy, tôi khuyên bạn nên mã hóa bí mật của bạn trước khi lưu trữ chúng trong AccountManager. Bạn có thể sử dụng nhiều thư viện Mã hóa khác nhau như AESCrypt hoặc AESCrypto

Một tùy chọn khác là sử dụng thư viện Conceal . Nó đủ an toàn cho Facebook và dễ sử dụng hơn AccountManager. Đây là đoạn mã để lưu tệp bí mật bằng Conceal.

byte[] cipherText = crypto.encrypt(plainText);
byte[] plainText = crypto.decrypt(cipherText);

2
Mẹo hay mà Che khuyết điểm. Trông rất dễ sử dụng. Và cho nhiều trường hợp sử dụng.
lagos

Không thể tìm thấy Che giấu qua liên kết. Nó có thể bị vô hiệu hóa
dùng1114

10

Bản thân SharedPreferences không phải là một vị trí an toàn. Trên một thiết bị đã root, chúng ta có thể dễ dàng đọc và sửa đổi tất cả các ứng dụng của SharedPrefereces xml. Vì vậy, các mã thông báo sẽ hết hạn tương đối thường xuyên. Nhưng ngay cả khi mã thông báo hết hạn mỗi giờ, các mã thông báo mới hơn vẫn có thể bị đánh cắp khỏi SharedPreferences. Android KeyStore nên được sử dụng để lưu trữ lâu dài và truy xuất các khóa mật mã sẽ được sử dụng để mã hóa mã thông báo của chúng tôi nhằm lưu trữ chúng trong ví dụ như SharedPreferences hoặc cơ sở dữ liệu. Các khóa không được lưu trữ trong quy trình của ứng dụng, vì vậy chúng khó bị xâm phạm hơn.

Vì vậy, liên quan hơn một địa điểm là cách chúng có thể được bảo mật, ví dụ như sử dụng JWT tồn tại ngắn hạn được ký mã hóa, mã hóa chúng bằng Android KeyStore và gửi chúng bằng một giao thức an toàn


9
Sau đó, chúng tôi có thể lưu trữ chúng ở đâu?
Milind Mevada,

2
  1. Từ ngăn Dự án của Android Studio, chọn "Tệp Dự án" và tạo tệp mới có tên "keystore.properties" trong thư mục gốc của dự án của bạn.

nhập mô tả hình ảnh ở đây

  1. Mở tệp "keystore.properties" và lưu Mã thông báo truy cập và Bí mật của bạn trong tệp.

nhập mô tả hình ảnh ở đây

  1. Bây giờ hãy tải bài đọc Access Token and Secret trong tệp build.gradle của mô-đun ứng dụng của bạn . Sau đó, bạn cần xác định biến BuildConfig cho Mã thông báo truy cập và Bí mật để bạn có thể truy cập trực tiếp chúng từ mã của mình. Build.gradle của bạn có thể trông giống như sau:

    ... ... ... 
    
    android {
        compileSdkVersion 26
    
        // Load values from keystore.properties file
        def keystorePropertiesFile = rootProject.file("keystore.properties")
        def keystoreProperties = new Properties()
        keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
    
        defaultConfig {
            applicationId "com.yourdomain.appname"
            minSdkVersion 16
            targetSdkVersion 26
            versionCode 1
            versionName "1.0"
            testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    
            // Create BuildConfig variables
            buildConfigField "String", "ACCESS_TOKEN", keystoreProperties["ACCESS_TOKEN"]
            buildConfigField "String", "SECRET", keystoreProperties["SECRET"]
        }
    }
  2. Bạn có thể sử dụng Mã truy cập và Bí mật trong mã của mình như sau:

    String accessToken = BuildConfig.ACCESS_TOKEN;
    String secret = BuildConfig.SECRET;

Bằng cách này, bạn không cần lưu trữ Mã truy cập và Bí mật ở dạng văn bản thuần túy bên trong dự án của mình. Vì vậy, ngay cả khi ai đó dịch ngược APK của bạn, họ sẽ không bao giờ nhận được Mã truy cập và Bí mật của bạn khi bạn đang tải chúng từ tệp bên ngoài.


1
Có vẻ như không có sự khác biệt khi tạo một tệp thuộc tính thay vì mã hóa cứng.
Dzshean

Tôi muốn viết Mã thông báo trong thời gian chạy có thể là mã thông báo của tôi luôn được thay đổi khi tôi mở ứng dụng của mình.
Rehan Sarwar

1
Đó là một cách rất tốt để lưu trữ một số mã thông báo như mã thông báo truy cập API. nếu bạn muốn lưu trữ thông tin đăng nhập của người dùng, NDK là một cách tốt hơn.
Eric,

7
Đây hoàn toàn không phải là cách bạn nên lưu trữ thông tin nhạy cảm trong ứng dụng của mình! Ngay cả khi kho lưu trữ không chứa dữ liệu bằng cách sử dụng phương pháp này (dữ liệu được đưa vào quá trình xây dựng), điều này sẽ tạo ra tệp BuildConfig có mã thông báo / bí mật ở dạng văn bản thuần túy để tất cả mọi người xem sau khi dịch ngược đơn giản.
Hrafn

-1

Bạn có thể bảo mật mã thông báo truy cập của mình bằng cách làm theo hai tùy chọn.

  1. Sử dụng lưu mã thông báo truy cập của bạn vào kho khóa android sẽ không bị ngược lại.
  2. Sử dụng hàm NDK với một số phép tính để lưu mã thông báo và NDK của bạn bằng mã c ++ mà rất khó để đảo ngược
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.