วิธีจัดเก็บโทเค็นการเข้าถึงและความลับใน Android อย่างปลอดภัย


123

ฉันจะใช้ oAuth เพื่อดึงอีเมลและรายชื่อติดต่อจาก Google ฉันไม่ต้องการขอให้ผู้ใช้ทุกครั้งที่เข้าสู่ระบบเพื่อรับโทเค็นการเข้าถึงและความลับ จากสิ่งที่ฉันเข้าใจฉันจำเป็นต้องจัดเก็บไว้กับแอปพลิเคชันของฉันทั้งในฐานข้อมูลหรือSharedPreferences. แต่ฉันค่อนข้างกังวลเกี่ยวกับด้านความปลอดภัยเกี่ยวกับเรื่องนี้ ฉันอ่านว่าคุณสามารถเข้ารหัสและถอดรหัสโทเค็นได้ แต่ผู้โจมตีเพียงแค่ถอดรหัส apk และคลาสของคุณและรับคีย์การเข้ารหัสนั้นเป็นเรื่องง่าย
วิธีใดดีที่สุดในการจัดเก็บโทเค็นเหล่านี้อย่างปลอดภัยใน Android


1
ฉันจะจัดเก็บคีย์และความลับของผู้บริโภคได้อย่างไร (การเชื่อมแบบแข็งจะไม่ปลอดภัย) ฉันต้องการให้พวกเขาขอ accesstoken และความลับ .. แอพอื่น ๆ ที่มีอยู่โดยใช้ oauth ทำได้อย่างไร? อืมสุดท้ายด้วย oauth คุณต้องดูแลปัญหาด้านความปลอดภัยให้มากขึ้นสำหรับฉัน .... ฉันต้องเก็บโทเค็น / ความลับของผู้บริโภคอย่างปลอดภัยรวมถึงการเข้าถึงและความลับด้วย .... ในที่สุดมันก็ไม่ง่ายไปกว่านี้ แค่เก็บชื่อผู้ใช้ / รหัสผ่านของผู้ใช้ที่เข้ารหัสไว้? ... สุดท้ายแล้วไม่ดีกว่าเหรอ? ฉันยังไม่เห็นว่า oauth ดีกว่าอย่างไร ...
ใช่

บอกหน่อยได้ไหม.. ไฟล์ไหนเก็บโทเค็นการเข้าถึง ?? ฉันยังใหม่กับ Android และได้ลองใช้แอปพลิเคชัน Plus ตัวอย่าง แต่ฉันไม่พบสิ่งนี้จากที่ใดก็ได้ [GoogleAuthUtil.getToken () วิธีการ]
Abhishek Kaushik

คำตอบ:


117

เก็บไว้เป็นตั้งค่าที่ใช้ร่วมกัน โดยค่าเริ่มต้นจะเป็นแบบส่วนตัวและแอปอื่น ๆ ไม่สามารถเข้าถึงได้ บนอุปกรณ์ที่รูทหากผู้ใช้อนุญาตอย่างชัดเจนในการเข้าถึงแอพบางตัวที่พยายามอ่านแอพนั้นอาจใช้งานได้ แต่คุณไม่สามารถป้องกันสิ่งนั้นได้ สำหรับการเข้ารหัสคุณจะต้องให้ผู้ใช้ป้อนข้อความรหัสผ่านถอดรหัสทุกครั้ง (จึงเป็นการเอาชนะวัตถุประสงค์ของการแคชข้อมูลรับรอง) หรือบันทึกคีย์ลงในไฟล์และคุณจะได้รับปัญหาเดียวกัน

มีประโยชน์บางประการในการจัดเก็บโทเค็นแทนรหัสผ่านชื่อผู้ใช้จริง:

  • แอพของบุคคลที่สามไม่จำเป็นต้องรู้รหัสผ่านและผู้ใช้สามารถมั่นใจได้ว่าพวกเขาส่งไปยังไซต์ดั้งเดิมเท่านั้น (Facebook, Twitter, Gmail และอื่น ๆ )
  • แม้ว่าจะมีคนขโมยโทเค็น แต่ก็ไม่เห็นรหัสผ่าน (ซึ่งผู้ใช้อาจใช้ในไซต์อื่นด้วย)
  • โดยทั่วไปโทเค็นจะมีอายุการใช้งานและหมดอายุหลังจากช่วงเวลาหนึ่ง
  • โทเค็นสามารถเพิกถอนได้หากคุณสงสัยว่าถูกบุกรุก

1
ขอบคุณสำหรับการตอบกลับ! แต่จะรู้ได้อย่างไรว่าคีย์ผู้บริโภคของฉันถูกบุกรุก มันยากที่จะบอก .. ตกลงเกี่ยวกับการจัดเก็บโทเค็นการเข้าถึงและความลับโอเคฉันบันทึกไว้ในค่ากำหนดที่ใช้ร่วมกันและเข้ารหัสพวกเขา แต่คีย์และความลับของผู้บริโภคล่ะ ฉันไม่สามารถจัดเก็บไว้ในค่ากำหนดที่ใช้ร่วมกันได้ (ฉันจะต้องเขียนรหัสผู้ใช้และรหัสลับอย่างชัดเจนในรหัสเพื่อบันทึกไว้ในรูปแบบที่ใช้ร่วมกันตั้งแต่แรก) .. ไม่รู้ว่าคุณเข้าใจที่ฉันหมายถึงหรือไม่
yeahman

2
คุณต้องใส่แอปในลักษณะที่สับสน (ค่อนข้าง) ไม่ชัดเจนเพราะจะไม่สามารถมองเห็นได้ในทันทีหลังจากการถอดรหัสหรือใช้เว็บแอปพร็อกซีการตรวจสอบความถูกต้องของคุณเองที่มีคีย์และความลับ การใส่ไว้ในแอปนั้นง่ายกว่าอย่างเห็นได้ชัดและหากคิดว่าความเสี่ยงของคนที่พยายามแตกแอปของคุณนั้นต่ำเพียงพอให้ใช้แนวทางนั้น BTW จุดด้านบนสำหรับรหัสผ่านผู้ใช้ หากคุณพบว่ารหัส / ความลับของผู้บริโภคของคุณถูกบุกรุกคุณสามารถเพิกถอนได้เช่นกัน (แน่นอนว่าจะทำให้แอปของคุณเสียหาย)
Nikolay Elenkov

1
@NikolayElenkov: คุณเขียนว่า 'สำหรับการเข้ารหัสคุณต้องให้ผู้ใช้ป้อนข้อความรหัสผ่านถอดรหัสทุกครั้ง (ซึ่งจะเป็นการเอาชนะวัตถุประสงค์ของการแคชข้อมูลรับรอง) หรือบันทึกคีย์ลงในไฟล์และคุณจะได้รับปัญหาเดียวกัน' . จะเกิดอะไรขึ้นหากแคร็กเกอร์ย้อนกลับแอปของคุณเพื่อรับข้อมูลเชิงลึกว่าการเข้ารหัสทำงานอย่างไร การป้องกันของคุณอาจพังได้ เป็นแนวทางปฏิบัติที่ดีที่สุดในการจัดเก็บข้อมูลดังกล่าว (โทเค็นการเข้ารหัส ... ) โดยใช้รหัสดั้งเดิมหรือไม่
anhldbk

1
หากล้างข้อมูลแอปโทเค็นการรีเฟรชจะหายไปซึ่งอาจไม่ใช่สิ่งที่ผู้ใช้ต้องการ
RDS

1
นี่ไม่ใช่วิธีที่ดีที่สุดในการจัดเก็บโทเค็นอีกต่อไปในปัจจุบัน!
Rahul Rastogi

19

คุณสามารถเก็บไว้ในAccountManager ถือว่าเป็นแนวทางปฏิบัติที่ดีที่สุดตามคนเหล่านี้

ใส่คำอธิบายภาพที่นี่

นี่คือคำจำกัดความอย่างเป็นทางการ:

คลาสนี้ให้การเข้าถึงรีจิสทรีส่วนกลางของบัญชีออนไลน์ของผู้ใช้ ผู้ใช้ป้อนข้อมูลรับรอง (ชื่อผู้ใช้และรหัสผ่าน) หนึ่งครั้งต่อบัญชีอนุญาตให้แอปพลิเคชันเข้าถึงแหล่งข้อมูลออนไลน์ด้วยการอนุมัติ "คลิกเดียว"

สำหรับคำแนะนำโดยละเอียดเกี่ยวกับวิธีใช้ AccountManager:

อย่างไรก็ตามในตอนท้าย AccountManager จะจัดเก็บโทเค็นของคุณเป็นข้อความธรรมดาเท่านั้น ดังนั้นฉันขอแนะนำให้เข้ารหัสความลับของคุณก่อนที่จะเก็บไว้ใน AccountManager คุณสามารถใช้ไลบรารีการเข้ารหัสต่างๆเช่นAESCryptหรือAESCrypto

อีกตัวเลือกหนึ่งคือการใช้ห้องสมุดปกปิด ปลอดภัยเพียงพอสำหรับ Facebook และใช้งานง่ายกว่า AccountManager มาก นี่คือข้อมูลโค้ดสำหรับบันทึกไฟล์ลับโดยใช้ Conceal

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

2
เคล็ดลับดีๆที่ปกปิด ดูใช้งานง่ายมาก และสำหรับกรณีการใช้งานจำนวนมาก
ลากอส

ไม่พบ Conceal ผ่านลิงก์ อาจถูกปิดการใช้งาน
user1114

10

SharedPreferences ไม่ใช่ตำแหน่งที่ปลอดภัย บนอุปกรณ์ที่รูทเราสามารถอ่านและปรับเปลี่ยน SharedPrefereces xml ของแอปพลิเคชันทั้งหมดได้อย่างง่ายดาย ดังนั้นโทเค็นควรหมดอายุค่อนข้างบ่อย แต่แม้ว่าโทเค็นจะหมดอายุทุก ๆ ชั่วโมงโทเค็นที่ใหม่กว่าก็ยังสามารถขโมยได้จาก SharedPreferences ควรใช้ Android KeyStore สำหรับการจัดเก็บระยะยาวและการดึงคีย์การเข้ารหัสซึ่งจะใช้ในการเข้ารหัสโทเค็นของเราเพื่อเก็บไว้ในเช่น SharedPreferences หรือฐานข้อมูล คีย์จะไม่ถูกเก็บไว้ในกระบวนการของแอปพลิเคชันดังนั้นจึงยากที่จะถูกบุกรุก

สิ่งที่เกี่ยวข้องมากกว่าสถานที่คือวิธีที่พวกเขาสามารถรักษาความปลอดภัยได้เช่นการใช้ JWT ที่มีอายุสั้นที่เซ็นชื่อแบบเข้ารหัสเข้ารหัสโดยใช้ Android KeyStore และส่งด้วยโปรโตคอลที่ปลอดภัย


9
แล้วเราจะเก็บไว้ที่ไหน?
Milind Mevada

2
  1. จากบานหน้าต่างโครงการของ Android Studio ให้เลือก "ไฟล์โครงการ" และสร้างไฟล์ใหม่ชื่อ "keystore.properties" ในไดเรกทอรีรากของโปรเจ็กต์

ใส่คำอธิบายภาพที่นี่

  1. เปิดไฟล์ "keystore.properties" และบันทึก Access Token และ Secret ในไฟล์

ใส่คำอธิบายภาพที่นี่

  1. ตอนนี้โหลดอ่าน Access Token และ Secret ในไฟล์build.gradleของโมดูลแอปของคุณ จากนั้นคุณต้องกำหนดตัวแปร BuildConfig สำหรับ Access Token และ Secret ของคุณเพื่อให้คุณสามารถเข้าถึงได้โดยตรงจากรหัสของคุณ build.gradleของคุณอาจมีลักษณะดังนี้:

    ... ... ... 
    
    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. คุณสามารถใช้ Access Token และ Secret ในรหัสของคุณได้ดังนี้:

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

ด้วยวิธีนี้คุณไม่จำเป็นต้องจัดเก็บโทเค็นการเข้าถึงและความลับเป็นข้อความธรรมดาภายในโครงการของคุณ ดังนั้นแม้ว่าจะมีคนถอดรหัส APK ของคุณพวกเขาก็จะไม่ได้รับโทเค็นการเข้าถึงและความลับของคุณในขณะที่คุณกำลังโหลดจากไฟล์ภายนอก


1
ดูเหมือนว่าจะไม่มีความแตกต่างที่การสร้างไฟล์คุณสมบัติแทนการเข้ารหัสยาก
Dzshean

ฉันต้องการเขียนโทเค็นในเวลาทำงานอาจเป็นเพราะโทเค็นของฉันมีการเปลี่ยนแปลงทุกครั้งเมื่อฉันเปิดแอป
Rehan Sarwar

1
เป็นวิธีที่ดีมากในการจัดเก็บโทเค็นเช่นโทเค็นการเข้าถึง API หากคุณต้องการเก็บข้อมูลรับรองผู้ใช้ NDK เป็นวิธีที่ดีกว่า
Eric

7
นี่ไม่ใช่วิธีที่คุณควรจัดเก็บข้อมูลที่ละเอียดอ่อนในแอปพลิเคชันของคุณอย่างแน่นอน! แม้ว่าที่เก็บจะไม่มีข้อมูลโดยใช้วิธีการนี้ (ข้อมูลจะถูกแทรกเข้าไปในกระบวนการสร้าง) สิ่งนี้จะสร้างไฟล์ BuildConfig ที่มีโทเค็น / ความลับเป็นข้อความธรรมดาเพื่อให้ทุกคนเห็นหลังจากการถอดรหัสอย่างง่าย
Hrafn

-1

คุณสามารถรักษาความปลอดภัยในการเข้าถึงโทเค็นได้โดยทำตามสองตัวเลือก

  1. ใช้บันทึกโทเค็นการเข้าถึงของคุณลงในที่เก็บคีย์ของ Android ซึ่งจะไม่ย้อนกลับ
  2. ใช้ฟังก์ชัน NDK กับการคำนวณบางอย่างที่บันทึกโทเค็นและ NDK ของคุณด้วยรหัส c ++ ซึ่งยากที่จะย้อนกลับ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.