2012-03-16 12 views
10

Kullanıcıların bir API anahtarı kullanarak kimliklerini doğrulamasına izin veren bir Java kodu çalıştıran bir tomcat sunucum var. İstek SHA256 ile oluşturulan bir HMAC kullanır. İstekte bulunmak için kullanıyorum bir Ruby istemcisi var ve şifreleme için yeni olduğum için eşleşen bir HMAC oluşturmak için zor bir zaman geçiriyorum. URL'yi güvenli hale getirmemeyi denedim ve bu da eşleşiyor. Bu yüzden gerçekten de Ruby istemcisinin URL güvenli sürümü ile eşleşmesini nasıl sağlayabileceğimi merak ediyorum (Java kodunu değiştiremediğimden). Sonunda sadece ekstra bir karakter var. Herhangi bir yardım için şimdiden teşekkür ederiz.Ruby, Java ile eşleşmesi güvenli olan SHA256 için HMAC'ı nasıl oluşturdu?

Ruby için 1.9.3 ve Java kullanıyorum 6u31'i apache'den commons-codec-1.6.jar kitaplığı ile birlikte kullanıyorum.

Kod

Yakut:

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); 
    } 
} 

Çıktı

Yakut:

Encoded (Url Safe): QgYLqGm1M4qozdEjGC_CnJ8CdBm2jQpsU85kSWFcjKM= 
Encoded   : QgYLqGm1M4qozdEjGC/CnJ8CdBm2jQpsU85kSWFcjKM= 

Java:

Encoded (Url Safe): QgYLqGm1M4qozdEjGC_CnJ8CdBm2jQpsU85kSWFcjKM 
Encoded   : QgYLqGm1M4qozdEjGC/CnJ8CdBm2jQpsU85kSWFcjKM= 

cevap

6

Yakut sondaki '=' kaldırmaz - bu mutlak bir gereklilik değildir, bunu sadece bunları kaldırmayı bazı uygulamalarda arzu olabileceğini belirtiyor RFC 4648 okuyabilirsiniz olarak . Ancak bunun dışında, Ruby'nin URL güvenli kodlamasının, Java'larla tam olarak aynı olacağı garanti edilir. Tam olarak ne ihtiyaç var

encoded_url_safe_.gsub!(/=+$/, "") 
+0

:

Yani yapmak için tek şey, örneğin bir düzenli ifade kullanabilirsiniz sondaki '==' kapalı şerit olduğunu. RFC 4648 referansı çok yardımsever ve kapsamlıydı. Sonunda '=' seçeneğinin isteğe bağlı olduğunu bilmiyordum. Bu regex kodunu ekledim ve işe yarıyor. Teşekkür ederim. – mvalley

İlgili konular