Ho un server tomcat che esegue un codice Java che consente agli utenti di autenticarsi utilizzando una chiave API. La richiesta utilizza un HMAC creato con SHA256. Ho un client Ruby che sto usando per fare la richiesta e dal momento che sono nuovo alla crittografia, sto avendo difficoltà a fargli generare un HMAC corrispondente. Ho provato a non renderlo URL sicuro, e che corrisponde. Quindi mi chiedo davvero come posso far sì che il client di Ruby corrisponda alla versione sicura per l'URL (dato che non posso modificare il codice Java). Alla fine ha un carattere extra =. Grazie in anticipo per qualsiasi aiuto.Come ottenere Ruby generato HMAC per SHA256 che è sicuro da url per abbinare Java?
Per Ruby sto usando 1.9.3 e per Java sto usando 6u31 insieme alla libreria commons-codec-1.6.jar da apache.
Codice
Rubino:
require "openssl"
require "base64"
json_str = "{'community':'LG7B734A', 'login_id':'user1', 'time':'1331928899'}"
digest = OpenSSL::Digest::Digest.new("sha256")
key = [ "4cc45e4258121c3fec84147673e1bd88e51b1c177aafcfa2da72bd4655c9f933" ]
hmac = OpenSSL::HMAC.digest(digest, key.pack("H*"), json_str)
encoded_url_safe = Base64.urlsafe_encode64(hmac)
encoded = Base64.encode64(hmac)
puts("Encoded (Url Safe): " + encoded_url_safe)
puts("Encoded : " + encoded)
Java:
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.Mac;
public class ExampleHMAC
{
public static void main(String[] args) throws Exception
{
String key = "4cc45e4258121c3fec84147673e1bd88e51b1c177aafcfa2da72bd4655c9f933";
byte[] keyBytes = Hex.decodeHex(key.toCharArray());
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "HmacSHA256");
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(keySpec);
String jsonStr = "{'community':'LG7B734A', 'login_id':'user1', 'time':'1331928899'}";
byte[] hmacBytes = mac.doFinal(jsonStr.getBytes());
String encodedUrlSafe = Base64.encodeBase64URLSafeString(hmacBytes);
String encoded = Base64.encodeBase64String(hmacBytes);
System.out.println("Encoded (Url Safe): " + encodedUrlSafe);
System.out.println("Encoded : " + encoded);
}
}
uscita
Rubino:
Encoded (Url Safe): QgYLqGm1M4qozdEjGC_CnJ8CdBm2jQpsU85kSWFcjKM=
Encoded : QgYLqGm1M4qozdEjGC/CnJ8CdBm2jQpsU85kSWFcjKM=
Java:
Encoded (Url Safe): QgYLqGm1M4qozdEjGC_CnJ8CdBm2jQpsU85kSWFcjKM
Encoded : QgYLqGm1M4qozdEjGC/CnJ8CdBm2jQpsU85kSWFcjKM=
Questo è esattamente quello che mi serviva. Il riferimento a RFC 4648 è stato molto utile e approfondito. Non sapevo che il trailing '=' fosse opzionale. Ho aggiunto il codice regex e funziona. Grazie. – mvalley