2011-09-30 56 views
10

Tôi có một bảng SQL với tên người dùng và mật khẩu. Các mật khẩu được mã hóa bằng phương thức digest() của MessageDigest. Nếu tôi mã hóa mật khẩu - giả sử "abcdef12" - với phương thức digest() của MessageDigest và sau đó chuyển đổi nó thành giá trị thập lục phân, thì String khác với nếu tôi làm như vậy bằng cách sử dụng phương thức SHA1 của PHP. Tôi hy vọng những giá trị này sẽ giống hệt nhau.Thuật toán MessageDigest SHA1 của Java trả về kết quả khác với hàm SHA1 của hàm php

Mã được sử dụng để mã hóa các mật khẩu:

MessageDigest md = MessageDigest.getInstance("SHA-1"); 
byte[] passbyte; 
passbyte = "abcdef12".getBytes("UTF-8"); 
passbyte = md.digest(passbyte); 

Việc quy đổi của String để hệ thập lục phân được thực hiện bằng phương pháp này:

public static String convertStringToHex(String str) { 

    char[] chars = str.toCharArray(); 

    StringBuffer hex = new StringBuffer(); 
    for (int i = 0; i < chars.length; i++) { 
     hex.append(Integer.toHexString((int) chars[i])); 
    } 

    return hex.toString(); 
} 

Mật khẩu: abcdef12

Dưới đây là mật khẩu được trả về bởi rất nhiều trình tạo trực tuyến SHA1-băm và hàm PHP SHA1(): d253e3b d69ce1e7ce6074345fd5faa1a3c2e89ef

Dưới đây là mật khẩu như mã hóa bởi MessageDigest: d253e3bd69ce1e7ce674345fd5faa1a3c2e2030ef

Tôi quên cái gì?

Igor.

Chỉnh sửa: Tôi đã tìm thấy ai đó có vấn đề tương tự: C# SHA-1 vs. PHP SHA-1...Different Results?. Giải pháp là thay đổi mã hóa .. nhưng tôi không thể thay đổi mã hóa ở phía máy chủ vì các mật khẩu trong bảng SQL đó không được tạo bởi ứng dụng của tôi. Tôi sử dụng mã hóa SHA1 phía máy khách bằng cách sử dụng lớp JavaScript SHA1 (chính xác hơn: lớp Google Toolkit-class). Nó hoạt động và mã hóa các chuỗi như mong đợi, nhưng dường như sử dụng các ký tự ASCII ..

Trả lời

3

Không có gì liên quan đến mã hóa. Đầu ra sẽ hoàn toàn khác.

Để bắt đầu, chức năng của bạn convertStringToHex() không xuất ra số 0 đứng đầu, nghĩa là, 07 sẽ trở thành chỉ 7.

Phần còn lại (thay đổi 89 thành 2030) cũng có khả năng liên quan đến chức năng đó. Hãy thử xem xét giá trị của passbyte sau passbyte = md.digest(passbyte);.

+0

Cảm ơn bạn! Câu trả lời của bạn đã giải quyết được vấn đề của tôi. Tôi đã thất bại trong việc chuyển đổi mảng byte thành chuỗi thập lục phân đúng cách! Tôi đã sử dụng phương pháp này từ @stivlo và nó hoạt động rất tốt! Tôi sẽ đánh dấu phản ứng này là chính xác, mặc dù trong trường hợp này tôi ước tôi có thể đánh dấu cả hai câu trả lời cho trước là câu trả lời chính xác! Cảm ơn cả hai người! – Igor

5

Tôi có cùng tiêu hóa như PHP với hàm băm Java-1 SHA tôi:?

public static String computeSha1OfString(final String message) 
    throws UnsupportedOperationException, NullPointerException { 
     try { 
       return computeSha1OfByteArray(message.getBytes(("UTF-8"))); 
     } catch (UnsupportedEncodingException ex) { 
       throw new UnsupportedOperationException(ex); 
     } 
} 

private static String computeSha1OfByteArray(final byte[] message) 
    throws UnsupportedOperationException { 
     try { 
      MessageDigest md = MessageDigest.getInstance("SHA-1"); 
      md.update(message); 
      byte[] res = md.digest(); 
      return toHexString(res); 
     } catch (NoSuchAlgorithmException ex) { 
      throw new UnsupportedOperationException(ex); 
     } 
} 

tôi đã thêm vào của tôi kiểm tra đơn vị:

String sha1Hash = StringHelper.computeSha1OfString("abcdef12"); 
assertEquals("d253e3bd69ce1e7ce6074345fd5faa1a3c2e89ef", sha1Hash); 

Mã nguồn đầy đủ cho lớp là on github.

+0

Thật vậy - mã của bạn tạo ra đúng SHA1 (hoặc đúng hơn: giống như SHA1 của php). Tuy nhiên, tôi đang viết một ứng dụng phải đăng nhập vào cơ sở dữ liệu hiện có. Cơ sở dữ liệu đó không được tạo ra bởi chính tôi (và cả mã hóa mật khẩu) cũng không được tạo ra. Nhưng ** nó sử dụng MessageDigest như được viết trong ví dụ của tôi ** và do đó chạy Base64.decode trên String đó trả về một kết quả khác (kết quả được chỉ ra trong ví dụ của tôi) chứ không phải kết quả chính xác của bạn, mà tôi cũng sử dụng JavaScript SHA1- lớp học. Có cách nào để so sánh chúng không? Tôi không biết MessageDigest đã trả lại kết quả khác như thế nào. – Igor

2

Hãy thử điều này - nó đang làm việc cho tôi:

MessageDigest md = MessageDigest.getInstance(algorithm); 
md.update(original.getBytes()); 
byte[] digest = md.digest(); 
StringBuffer sb = new StringBuffer(); 
for (byte b : digest) { 
    sb.append(Integer.toString((b & 0xff) + 0x100, 16).substring(1)); 
} 
return sb.toString(); 

Kính trọng, Konki

2

Hoặc thử này:

MessageDigest md = MessageDigest.getInstance("SHA-1"); 
md.update(clearPassword.getBytes("UTF-8")); 
return new BigInteger(1 ,md.digest()).toString(16)); 

Cheers Roy

Các vấn đề liên quan