2012-07-12 12 views
8

Tôi có nên dán khóa công khai thực sự của ứng dụng của tôi ngay vào giá trị của biến này không?Thanh toán trên Android - trong tệp Security.java thì base64EncodedPublicKey có phải là giá trị được mã hóa không?

Hoặc tôi nên mã hóa nó và sau đó bất cứ điều gì các chuỗi mã hóa là, tôi muốn làm cho chuỗi đó vào giá trị của biến này?

Nó nên là gì?

+0

Ứng dụng của bạn có thành phần máy chủ không? –

+0

@JohnJSmith Xin chào John, có chứ :) – Genadinik

Trả lời

4

Khóa công khai có trong Bảng điều khiển dành cho nhà phát triển Android của bạn (có thể tìm thấy trong 'Chỉnh sửa hồ sơ') đã được mã hóa Base64. Chỉ cần sao chép dán nội dung của khóa trong tệp nguồn của bạn. Ví dụ, nếu bạn có một cái gì đó như thế này:

enter image description here

Sau đó, trong Security.java của bạn:

String base64EncodedPublicKey = "MIIBIjANBgkqhkiG9w0BAQ......"; 
+0

base64EncodedPublicKey sẽ là chìa khóa công khai của ứng dụng của bạn (mà bạn nhận được từ bảng điều khiển dành cho nhà phát triển trên Google Play). Đây không phải là khóa công khai của nhà phát triển của bạn, đó là khóa công khai * dành riêng cho ứng dụng *. Thay vì chỉ lưu trữ toàn bộ chuỗi ký tự ở đây được nhúng trong chương trình, hãy tạo khóa ở thời gian chạy từ các phần hoặc sử dụng thao tác bit (ví dụ: XOR với một số chuỗi khác) để ẩn khóa thực. Chìa khóa chính nó không phải là thông tin bí mật, nhưng chúng tôi không muốn làm cho kẻ tấn công dễ dàng thay thế khóa công khai bằng một trong những thông điệp giả mạo của họ và sau đó từ máy chủ. – rocknow

+0

Điều này đã trở lại vào những ngày cũ, nơi chúng tôi đã có một khóa phát triển duy nhất, được sử dụng để cấp phép và trong ứng dụng. – aromero

+2

Khóa công khai RSA được mã hóa Base64 của bạn cho thanh toán cấp phép và thanh toán trong ứng dụng đã chuyển và hiện có thể tìm thấy trong Goggle Play bằng cách chọn Ứng dụng của bạn, sau đó nhấp vào tab "Dịch vụ & API". – birdman

1

Bạn cần khóa công khai trong mã nguồn của chương trình để bạn có thể kiểm tra chữ ký. Có, không có rủi ro không thể tránh khỏi mà một cracker sẽ tìm thấy nó, thay thế nó bằng một giả, và ăn chương trình mua hàng giả của bạn.

Bạn không thể hoàn toàn che giấu chìa khóa từ con mắt tò mò, nhưng bạn có thể xáo trộn. Bạn có thể chia chuỗi Base64 thành nhiều chuỗi ký tự ở các vị trí khác nhau và nối chúng trước khi sử dụng. Tốt hơn hãy cung cấp cho các tên không kín đáo (không phải như MY_PUBLIC_KEY_PART_4). Bạn cũng có thể áp dụng thêm một lớp mã hóa mềm cho nó - giống như XOR một giá trị. Bạn có thể thêm kiểm tra tính toàn vẹn - đảm bảo khóa không bị giả mạo (giả sử, lưu trữ mã băm của khóa ở nơi khác và kiểm tra). Nhưng điều này vẫn là an ninh thông qua sự tối tăm - một hacker đủ quyết tâm sẽ vượt qua được.

Cũng xem xét ProGuard, được xây dựng trong công cụ mã obfuscation.

+3

Bạn không cần ẩn hoặc làm xáo trộn khóa công cộng. Google sẽ ký các yêu cầu bằng khóa bí mật (mà bạn (nhà phát triển) không có và sẽ không có mặt trong đơn đăng ký của bạn). Khóa công khai chỉ được sử dụng để xác minh chữ ký đó. Một cracker không thể tạo ra một giao dịch giả mạo bằng cách sử dụng khóa công khai. – aromero

+1

Một cracker có thể thay thế chìa khóa công cộng trong bộ nhớ ứng dụng với riêng của họ, và ký mua hàng với khóa riêng của họ. Đó là lý do Google khuyên bạn nên làm xáo trộn. –

+0

Bạn nói đúng, tôi nghĩ bạn đang nói về chìa khóa. – aromero

0

Nếu bạn có một thành phần máy chủ như là một phần của ứng dụng của bạn, sau đó bạn có thể di chuyển hầu hết các yếu tố bảo mật của bạn, bao gồm khóa công khai của bạn, máy chủ của bạn. Trên máy chủ, bạn có thể tạo nonce và xác minh giao dịch mua (tôi đã chuyển tài khoản của tôi sang dịch vụ WCF RESTFul). Nếu thành phần máy chủ của bạn dựa trên .NET, thì có thể bạn sẽ phải tạo một mô-đun và một số mũ từ khóa công khai của bạn để bạn có thể sử dụng lớp RNGCryptoServiceProvider. Có một video Google I/O cung cấp tổng quan to In-App Billing trong số các video khác.

+0

Bạn có ý nghĩa gì bởi ~ "** mô-đun và số mũ **? Nó có hoạt động với khóa được mã hóa base64 cho Thanh toán trong ứng dụng không? –

2

Như đoạn code mẫu Google cho thanh toán trong ứng dụng nói, bạn nên xáo trộn khóa công khai này.

Thay vì chỉ lưu trữ toàn bộ chuỗi literal đây nhúng trong chương trình , xây dựng chìa khóa trong thời gian chạy từ mảnh hoặc sử dụng thao tác bit (ví dụ, XOR với một số chuỗi khác) để ẩn phím thực tế. Bản thân khóa không phải là thông tin bí mật, nhưng chúng tôi không muốn giúp kẻ tấn công dễ dàng thay thế khóa công khai bằng một số của riêng họ và sau đó là tin nhắn giả mạo từ máy chủ.

Tôi sử dụng mã Java rất đơn giản để tạo Lớp Java sẽ cung cấp cho tôi khóa công khai. Ý tưởng cơ bản là sử dụng đệ quy để tạo lại khóa bằng cách sử dụng lớp tĩnh bên trong. Nó chỉ là thức ăn cho suy nghĩ.

Đó là một "đủ tốt" cách tiếp cận đối với thị trường thích của tôi.Xem this stackexchange security question để biết thêm thông tin về việc làm xáo trộn.

public static void main(String[] args) throws Exception { 
    String className = genClassName(); 
    PrintWriter writer = new PrintWriter("C:\\" + className + ".java", "iso-8859-1"); 
    printClass(className, writer, "XXXXXX-YOUR-PUBLIC-KEY-GOES-HERE-XXXXXXX", true); 
    writer.close(); 
} 

private static String genClassName() { 
    return "Class" + UUID.randomUUID().toString().replaceAll("-", ""); 
} 

private static String printClass(String thisClass, PrintWriter writer, String key, boolean root) { 
    int split = key.length()/2; 
    if (split < 10) { 
     writer.println("public " + (root ? "" : "static") + " class " + thisClass + " {"); 
     writer.println("public static String get() {"); 
     writer.println("return \"" + key + "\";"); 
     writer.println("}"); 
     writer.println("}"); 
    } else { 
     String first = key.substring(0, split); 
     String last = key.substring(split, key.length()); 
     writer.println("public " + (root ? "" : "static") + " class " + thisClass + " {"); 
     String class1 = printClass(genClassName(), writer, first, false); 
     String class2 = printClass(genClassName(), writer, last, false); 
     writer.println("public static String get() {"); 
     writer.println("return " + class1 + ".get() + " + class2 + ".get();"); 
     writer.println("}"); 
     writer.println("}"); 
    } 

    return thisClass; 
}