2014-06-26 19 views
7

trong PHP tôi có chức năng sau:tại sao hash_hmac PHP ('sha256') cho kết quả khác nhau hơn so với java sha256_HMAC

base64_encode(hash_hmac('sha256', $data, $secret, false)); 

Tôi đang cố gắng để tạo ra một hàm trong Java mà sẽ cung cấp các kết quả tương tự cho các các thông số "dữ liệu" và "bí mật" giống nhau.

Tôi cố gắng để sử dụng chức năng này:

public static String base64sha256(String data, String secret) { 
    Mac sha256_HMAC = Mac.getInstance("HmacSHA256"); 
    SecretKeySpec secret_key = new SecretKeySpec(secret.getBytes(), "HmacSHA256"); 
    sha256_HMAC.init(secret_key); 
    byte[] res = sha256_HMAC.doFinal(data.getBytes()); 
    return Base64.encodeToString(res, Base64.NO_WRAP); 
} 

Nhưng tôi nhận được kết quả khác nhau cho cùng một đầu vào


Cập nhật: Chức năng này hoạt động. Thưởng thức.

public static String base64sha256(String data, String secret) { 
    String hash = null; 
    try { 
     Mac sha256_HMAC = Mac.getInstance("HmacSHA256"); 
     SecretKeySpec secret_key = new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA256"); 
     sha256_HMAC.init(secret_key); 
     byte[] res = sha256_HMAC.doFinal(data.getBytes("UTF-8")); 
     hash = getHex(res); 
     hash = Base64.encodeToString(hash.getBytes("UTF-8"), Base64.NO_WRAP); 
    } catch (Exception e){} 
    return hash; 
} 

static final String HEXES = "abcdef"; 
public static String getHex(byte [] raw) { 
    if (raw == null) { 
     return null; 
    } 
    final StringBuilder hex = new StringBuilder(2 * raw.length); 
    for (final byte b : raw) { 
     hex.append(HEXES.charAt((b & 0xF0) >> 4)) 
       .append(HEXES.charAt((b & 0x0F))); 
    } 
    return hex.toString(); 
} 
+0

mã hóa dữ liệu có thể? ANSI vs UTF-8 chẳng hạn? – gtgaxiola

+0

tôi đã cố gắng sử dụng getBytes ("UTF-8") trên cả hai thông số và nó vẫn không phải là kết quả tương tự như các phiên bản PHP –

+0

Xem Q & A http://stackoverflow.com/q/4680661/ nơi họ nói về 'String.getBytes() 'và http://stackoverflow.com/q/23066005/ những thứ này được tìm thấy trong phần" Related ". –

Trả lời

2

Đầu ra của hàm php là chữ số thập phân chữ thường khi thông số thứ tư là sai. Tuy nhiên, phiên bản java thứ hai của bạn sẽ tạo ra các chữ số hex chữ hoa. Hoặc sửa sự khác biệt của trường hợp hoặc bạn có thể thay đổi tham số thứ tư của hash_hmac thành true và nó có thể sẽ khớp với phiên bản Java đầu tiên của bạn.

+0

Giải quyết. Cảm ơn người đàn ông –

0

Đối với một người có thể phải đối mặt với một thay đổi nhỏ (không hoạt động) trong kết quả Java so với PHP, vấn đề của tôi là trả lại mã băm từ HmacSHA256 làm Chuỗi, trong khi bạn nên trả lại và chuyển đến Hex dưới dạng byte[]. Sau đây là các phương pháp làm việc để mô phỏng PHP hash_hmac()

public String hashValue(String message) { 
    byte[] hash = toHmacSHA256(message); 
    String hashHexed = toHex(hash); 
    return hashHexed; 
} 

private String toHex(byte[] value) { 
    String hexed = String.format("%040x", new BigInteger(1, value)); 
    return hexed; 
} 

private byte[] toHmacSHA256(String value) { 
    byte[] hash = null; 
    try { 
     SecretKey secretKey = new SecretKeySpec(PRIVATE_KEY.getBytes("UTF-8"), "HmacSHA256"); 
     Mac mac = Mac.getInstance("HmacSHA256"); 
     mac.init(secretKey); 
     hash = mac.doFinal(value.getBytes("UTF-8")); 

    } catch (NoSuchAlgorithmException e) { 
     e.printStackTrace(); 
    } catch (InvalidKeyException e) { 
     e.printStackTrace(); 
    } catch (UnsupportedEncodingException e) { 
     e.printStackTrace(); 
    } 

    return hash; 
} 
1

Nếu cố gắng để phù hợp với sản lượng drupal_hmac_base64 với Java 8, bạn có thể sử dụng đoạn mã sau:

final String ALGORITHM = "HmacSHA256"; 
     Mac mac = Mac.getInstance(ALGORITHM); 
     SecretKeySpec secret = new SecretKeySpec(authorizationKey.getBytes(), ALGORITHM); 

     mac.init(secret); 
     byte[] digest = mac.doFinal(body.getBytes()); 

     hash = Base64.getUrlEncoder().withoutPadding().encodeToString(digest); 

     return signature.equals(hash); 

Lưu ý rằng drupal trả về một băm sử dụng nguyên dữ liệu nhị phân (tham số thứ 3 TRUE). Ngoài ra, mã hóa base64 trong PHP khớp với bộ mã hóa cơ sở dữ liệu an toàn của URL và Tên tệp trong Java https://docs.oracle.com/javase/8/docs/api/java/util/Base64.html#url.

+0

đây là điều này giống như base64_encode (hash_hmac ('sha256', $ dữ liệu, $ bí mật, sai)) với Java 8 (đó là những gì Im đang cố gắng để đạt được)? –

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