Arrays.equals() vs MessageDigest.isEqual()

  Pi Ke        2015-05-14 22:03:29       20,252        0          English  简体中文  ภาษาไทย  Tiếng Việt 

Cả Arrays.equals()MessageDigest.isEqual() đều được sử dụng để so sánh sự bằng nhau của hai mảng. Chúng có thể được sử dụng thay thế cho nhau trong nhiều trường hợp. Tuy nhiên, chúng có một số khác biệt dẫn đến các trường hợp sử dụng khác nhau trong các ứng dụng thực tế.

Một điểm khác biệt là các mảng được truyền vào MessageDigest.isEqual() không thể là null trong khi điều đó không sao đối với Arrays.equals().

Sự khác biệt chính giữa hai phương thức này là Arrays.equals() không cố định thời gian trong khi MessageDigest.isEqual() cố định thời gian. Điều này có nghĩa là khi so sánh hai mảng, các mảng được so sánh từng byte một, Arrays.equals() sẽ trả về ngay lập tức đối với byte đầu tiên không bằng nhau. MessageDigest.isEqual() sẽ so sánh tất cả các byte trong mảng bất kể byte đầu tiên không bằng nhau ở đâu.

Việc triển khai Arrays.equals() là:

public static boolean equals(byte[] a, byte[] a2) {
    if (a==a2)
        return true;
    if (a==null || a2==null)
        return false;

    int length = a.length;
    if (a2.length != length)
        return false;

    for (int i=0; i<length; i++)
        if (a[i] != a2[i])
            return false;

    return true;
}

Từ vòng lặp for, Arrays.equals() là một phương pháp dừng nhanh. Nếu byte đầu tiên không bằng nhau, nó sẽ trả về ngay lập tức. Điều này thường có nghĩa là hiệu quả cao nhưng bảo mật thấp hơn. Trên thực tế, từ việc triển khai, phương thức này được thiết kế để có hiệu quả. Chúng có một vài kiểm tra để xác định xem hai mảng có bằng nhau nhanh chóng mà không cần thực sự so sánh nội dung của mảng.

Việc triển khai MessageDigest.isEqual() là:

public static boolean isEqual(byte[] digesta, byte[] digestb) {
    if (digesta.length != digestb.length) {
        return false;
    }

    int result = 0;
    // time-constant comparison
    for (int i = 0; i < digesta.length; i++) {
        result |= digesta[i] ^ digestb[i];
    }
    return result == 0;
}

Từ vòng lặp for, các mảng được so sánh hoàn toàn. Điều này có nghĩa là bảo mật cao nhưng hiệu quả thấp hơn.

Trong các hệ thống yêu cầu bảo mật cao, Arrays.equals() có thể dễ bị tấn công thời gian cố định. Ví dụ: nếu có một so sánh băm hoặc khóa bằng Arrays.equals(), kẻ tấn công có thể giả mạo một băm hoặc khóa và thực hiện so sánh với băm hoặc khóa thực tế. Chúng có thể đo thời gian cần thiết để Arrays.equals() trả về để hiểu có bao nhiêu byte khớp với băm hoặc khóa giả mạo. Sau hàng trăm hoặc hàng nghìn lần thử, chúng có thể tiết lộ băm và khóa thực tế. Để biết thêm chi tiết về cách thức hoạt động của cuộc tấn công này, bạn có thể đọc thêm tại A Lesson In Timing Attacks (or, Don’t use MessageDigest.isEquals).

Vì vậy, khi bạn quyết định sử dụng phương thức để so sánh hai mảng, vui lòng cân nhắc kỹ xem ứng dụng có quan tâm đến bảo mật hay hiệu quả không. Nếu hiệu quả là những gì bạn cần, hãy sử dụng Arrays.equals(), nhưng nếu bạn đang phát triển một sản phẩm bảo mật, hãy thận trọng và tiếp tục sử dụng MessageDigest.isDigest().

Hãy nhớ rằng tin tặc là một nhóm người "sử dụng mọi biện pháp có thể; không dừng lại ở bất cứ điều gì".

ARRAYS.EQUAL()  MESSAGEDIGEST.ISEQUAL()  JAVA  SECURITY 

       

  RELATED


  0 COMMENT


No comment for this article.



  RANDOM FUN

Where blue screen appears on a wedding

"Blue screen" has become one notorious symbol of Windows. Maybe you have seen the Windows blue screen in a few occasions. But have you see it on a wedding? The above is what happens on a wedding. What if Bill Gates attends a wedding and see this famous scene? The image source is dedicated to Sina We