Para resumir mi problema, quiero adaptar un algoritmo de cifrado escrito en Javascript al lado de Java. El contenido producido aquí se usa en el encabezado del servicio al que llamo. Pero aunque lo he intentado de muchas maneras, todavía no he podido encontrar el algoritmo real.
El algoritmo escrito en Javascript es el siguiente:
function doFunction() { apiSecret = "ZDhhODhlOTI2ZjFmNGQ5MDlhMzg5Y2JhZTQyOGUzNDY="; date = (new Date()).toUTCString(); signatureContentString = 'date: ' + date; signatureString = CryptoJS.HmacSHA1(signatureContentString, apiSecret).toString(CryptoJS.enc.Base64); authHeader = encodeURIComponent(signatureString); alert(authHeader); }El algoritmo que probé en el lado de Java es el siguiente:
public String createCredential(){ Date currentDate = new Date(); SimpleDateFormat simpleDateFormat = new SimpleDateFormat(Constants.RFC1123_PATTERN); simpleDateFormat.setTimeZone(TimeZone.getTimeZone("GMT")); String date = simpleDateFormat.format(currentDate); String signatureContentString = "date: "+date; byte[] bytes = HmacUtils.hmacSha1(Constants.apiSecret, signatureContentString); byte[] encode = Base64.getEncoder().encode(bytes); String encoded = URLEncoder.encode(encode.toString(), StandardCharsets.UTF_8); return encoded; }Ejemplo de salida cuando lo pruebo en el lado de javascript:
rJxRUgl1%2Bxj5UZSC9rZAHxSl7fw%3DSalida de ejemplo cuando lo pruebo en el lado de Java:
%5BB%4079c7ad7fLos formatos no coinciden entre sí. Por cierto, si necesita la constante RFC1123_PATTERN;
public static final String RFC1123_PATTERN = "EEE, dd MMM yyyy HH:mm:ss z";encode.toString() devuelve un String que representa el byte[] , seg aquí , pero no, como probablemente suponga, una decodificación ASCII o UTF8.
Para este último uso en el código Java:
byte[] encode = Base64.getEncoder().encode(bytes); String encoded = URLEncoder.encode(new String(encode, StandardCharsets.UTF_8), StandardCharsets.UTF_8);o alternativamente:
String encode = Base64.getEncoder().encodeToString(bytes); String encoded = URLEncoder.encode(encode, StandardCharsets.UTF_8); Prueba:
Para la cadena de fecha Sat, 18 Jun 2022 17:07:55 GMT , ambos códigos devuelven el valor rSQNB1HOmHEPH982kd9ix0%2F%2F58A%3D .