2011-08-12 8 views
6

Tôi gặp sự cố với một số HMAC trên Android. Tôi đang sử dụng thuật toán SHA1 với mã sau hiển thị trên toàn bộ web khi tìm kiếm android hmac-sha1.Android HMAC-SHA1 Khác với Tiêu chuẩn Java HMAC-SHA1

 String base_string = "This is a test string"; 
     String key = "testKey"; 
     try { 
      Mac mac = Mac.getInstance("HmacSHA1"); 
      SecretKeySpec secret = new SecretKeySpec(key.getBytes("UTF-8"), mac.getAlgorithm()); 
      mac.init(secret); 
      byte[] digest = mac.doFinal(base_string.getBytes()); 

      String enc = new String(digest); 

      // Base 64 Encode the results 
      String retVal = Base64.encodeBase64String(enc.getBytes()); 
      Log.v(TAG, "String: " + base_string); 
      Log.v(TAG, "key: " + key); 
      Log.v(TAG, "result: " + retVal); 
     } catch (Exception e) { 
      System.out.println(e.getMessage()); 
     } 

Để kiểm tra mã này, tôi đã tạo một chương trình Java chuẩn đơn giản (thay thế cuộc gọi Log.v bằng System.out.println) để tôi có thể so sánh với phiên bản Android. Trong cả hai trường hợp, tôi đang sử dụng các giá trị thử nghiệm giống nhau cho base_string và khóa.

Ngoài ra, tôi đã xác minh các kết quả được mã hóa từ Java chuẩn với một số hàm PHP và máy chủ xác thực (sử dụng một số mã thông báo OAuth). Mã hoạt động tốt trong chương trình Java tiêu chuẩn tuy nhiên nó không hoạt động trong chương trình Android. Tôi đã thực hiện rất nhiều tìm kiếm và không thể tìm ra những gì là sai. Bất cứ ai từng trải nghiệm điều này?

Đây là kết quả từ java tiêu chuẩn và android ...

  • Java (và PHP): fH/+pz0J5XcPZH/d608zGSn7FKA=
  • Chương trình Android: fH/vv73vv709Ce+/vXcPZH/vv73vv71PMxkp77+9FO+/vQ==

Nhìn vào nó một chút tôi chắc chắn nó là chức năng hmac và không phải là mã hóa Base64, nơi nó được điều sai lầm khi so sánh các giá trị hmac phiên bản Android có tất cả các loại không gian bổ sung và các biểu tượng ký tự không rõ khác so với chương trình Java.

Mọi trợ giúp đều được đánh giá cao!

+1

Không thể tìm thấy phương thức 'android.util.Base64.encodeBase64String (...)' –

Trả lời

13

Tôi cho rằng đây là sự cố mã hóa chuỗi.

Bạn đang làm gì ở đây?

 String enc = new String(digest); 

     // Base 64 Encode the results 
     String retVal = Base64.encodeBase64String(enc.getBytes()); 

Bạn chuyển các byte trong chuỗi và sau đó quay lại mảng byte một lần nữa (sau đó mã hóa base-64).

Thay vào đó, làm điều này:

 String retVal = Base64.encodeBase64String(digest); 

Nói chung, không bao giờ sử dụng String.getBytes() hoặc new String(byte[]) nếu bạn muốn có một chương trình di động. Và không bao giờ cố gắng chuyển đổi một mảng byte tùy ý (không phải là một chuỗi trước đó) thành một chuỗi (không phải là một cái gì đó giống như Base64).

+0

Wow! Quá dễ! Tôi biết nó sẽ như thế nhưng tôi đã thực sự gãi đầu. Cảm ơn! Điều đó đã khắc phục được sự cố ngay lập tức. – nlbers

+0

+1 để có câu trả lời tuyệt vời :) –

+1

Bạn tìm phương thức encodeBase64String() ở đâu? Tôi không tìm thấy nó ở đâu cả. – Gabrielle