2012-10-16 19 views
14

Ben ticaret API imzalı istek çalışıyorum imzalıColdfusion CFHTTP bitfloor.com de DİNLENME istek gövdesini

Bitfloor bana verir (bir REST API var) Anahtar (yani 6bd2b780-00be-11e2-bde3-2837371c3c3a) aşağıdaki

2) Gizli Anahtar (yani oaFz62YpmbWiXwseMUSod53D8pOjdyVcweNYdiab/TSQqxk6IuemDvimNaQoA ==)

istekte için Bitfloor kesin talimatlar geçerli:

İstekler, 443 numaralı bağlantı noktasındaki (https) HTTPS POST istekleri olmalıdır. Her istek, gerekli başlıkları içermelidir (aşağıda listelenmiştir). Başlıklar, değişiklik yapılmasını önlemek için isteğinizi tanımlar, doğrular ve doğrular. başlıkları

bitfloor anahtar Eşsiz bir hesabınızı tanımlamak için bitfloor tarafından sağlanmaktadır. (Yani 6bd2b780-00be-11e2-bde3-2837371c3c3a)

bitfloor işareti işaret alanı, API anahtarına karşılık gelen gizli anahtarı kullanarak talep gövdesinin bir sha512-HMAC olup.

İsteğinizi imzalamak için: base64 gizli anahtarı raw baytlara (64 bayt) çöz. Http istek gövdesinin sha512-hmac imzanız için bu baytları kullanın. Base64 imzalama sonucunu kodlar ve bu başlık alanına gönderir.

bitfloor-passphrase Bu api anahtarı oluştururken belirttiğiniz parola. Unuttuğunuzda parolanızı kurtaramayız. Yeni bir API anahtarı oluşturmanız gerekecek.

bitfloor-sürüm ilgilendiğiniz kaynağın API sürümü. Tek geçerli değer şu anda 1


deneme yanılma tam sekiz saat sonra

ve herhangi için sürekli internet arama olduğu Bir tür içgörü veya bilgi, aşağıdaki kod, bir şekilde nasıl olabileceğine inandığım yere gelebileceğimi düşündüğüm kadar yakın bir şekilde olabilir, ne olursa olsun ne yazık olurum "Geçersiz İmza" ile geri döndüm. API.

<cffunction name="HMAC_SHA512" returntype="binary" access="public" output="false"> 
    <cfargument name="signKey" type="string" required="true"> 
    <cfargument name="signMessage" type="string" required="true"> 

    <cfset var jMsg = JavaCast("string",arguments.signMessage).getBytes("iso-8859-1")> 
    <cfset var jKey = JavaCast("string",arguments.signKey).getBytes("iso-8859-1")> 
    <cfset var key = createObject("java","javax.crypto.spec.SecretKeySpec")> 
    <cfset var mac = createObject("java","javax.crypto.Mac")> 
    <cfset key = key.init(jKey,"HmacSHA512")> 
    <cfset mac = mac.getInstance(key.getAlgorithm())> 
    <cfset mac.init(key)> 
    <cfset mac.update(jMsg)> 
    <cfreturn mac.doFinal()> 
</cffunction> 

ne işe yaradığını bilmiyorum: Burada

... Ben bugüne kadar ne İLK

olduğunu, birinin SHA512 imza yapmak yazdığı web üzerinde bu işlevi bulundu ama işe yaramaz ve hatasız yapar.

Bu işlevin benim uygulamamı ve isteği gerçekleştirme girişimi şu şekildedir: NOT: "nonce" değeri, istekle birlikte gönderilmesi gereken zorunlu bir paramdır.

<cffunction name="myorders"> 
    <cfset nonce  = dateDiff("s",createDateTime(2012,01,01,0,0,0),now())> 
    <cfset requestbody = "?nonce=#nonce#"> 
    <cfset key  = "oaFz62YpmbWiXwseMUSod53D8pOjdyVcweNYdiab/TSQqxk6IuemDvimNaQoA=="> 
    <cfset sign  = HMAC_SHA512(key,requestbody)> 
    <cfset signed  = binaryEncode(sign,"Base64")> 

    <!--- HTTP REQUEST ---> 
    <cfhttp url = "https://api.bitfloor.com/orders#requestbody#" 
     method = "post" 
     result = "bitfloor"> 

    <!--- HEADERS ---> 
    <cfhttpparam 
     type = "body" 
     value = requestbody> 
    <cfhttpparam 
     type = "header" 
     name = "bitfloor-key" 
     value = "6bd2b780-00be-11e2-bde3-2837371c3c3a"> 
    <cfhttpparam 
     type = "header" 
     name = "bitfloor-sign" 
     value = signed> 
    <cfhttpparam 
     type = "header" 
     name = "bitfloor-passphrase" 
     value = "mysecretpassphrase"> 
    <cfhttpparam 
     type = "header" 
     name = "bitfloor-version" 
     value = "1"> 
    </cfhttp> 
</cffunction> 

benim karışıklık çoğu tam olarak "istek gövdesi" ne bilmeden geldiğini düşünüyorlar. Belki de doğru şeyi imzalamam gibi hissediyorum.

Umarım, imzalanmış isteklere aşina olan bir Coldfusion programcısı vardır. Ben aklımın ucundayım.

Lütfen yardım edin! Namaste

cevap

2

O api kullanmadıysanız, ancak bazı testler yaptım ve aşağıdaki düzeltmelerle birlikte iş gibi görünüyor: secretKey değer base64 kodlanmış olduğundan

  • , imzalama işlevi için binaryDecode kullanması gerekir baytları düzgün şekilde çıkartın. String.getBytes(...) kullanmak tamamen farklı (ve yanlış) bir sonuç üretir.

  • beklenen istek gövdesi değeri sadece bağlıdır: (lider "?" olmadan) nonce=#nonceValue#

  • O aksi takdirde içeriği ayrıştırmak başarısız olur ve yanıttır, Content-Type=application/x-www-form-urlencoded başlığını gerektirecek gibi görünüyor

    : { "hatası": "hayır nonce belirtilen"}

Kod

<cfset apiKey = "6bd2b780-00be-11e2-bde3-2837371c3c3a"> 
<cfset secretKey = "oaFz62YpmbWiXwseMUSod53D8pOjdyVcweNYdiab/TSQqxk6IuemDvimNaQoA=="> 
<cfset passphrase = "your secret phrase"> 

<cfset requestBody = "nonce="& now().getTime()> 
<cfset signBytes = HMAC_SHA512(secretKey, requestbody)> 
<cfset signBase64 = binaryEncode(signBytes, "base64")> 

<cfhttp url="https://api.bitfloor.com/orders" method="post" port="443" result="bitfloor"> 
    <cfhttpparam type="header" name="Content-Type" value="application/x-www-form-urlencoded"> 
    <cfhttpparam type="header" name="bitfloor-key" value="#apiKey#"> 
    <cfhttpparam type="header" name="bitfloor-sign" value="#signBase64#"> 
    <cfhttpparam type="header" name="bitfloor-passphrase" value="#passphrase#"> 
    <cfhttpparam type="header" name="bitfloor-version" value="1"> 
    <cfhttpparam type="body" value="#requestBody#"> 
</cfhttp> 

<cfdump var="#bitfloor#" label="Response"> 

<cffunction name="HMAC_SHA512" returntype="binary" access="public" output="false"> 
    <cfargument name="base64Key" type="string" required="true"> 
    <cfargument name="signMessage" type="string" required="true"> 
    <cfargument name="encoding" type="string" default="UTF-8"> 

    <cfset var messageBytes = JavaCast("string",arguments.signMessage).getBytes(arguments.encoding)> 
    <cfset var keyBytes = binaryDecode(arguments.base64Key, "base64")> 
    <cfset var key = createObject("java","javax.crypto.spec.SecretKeySpec")> 
    <cfset var mac = createObject("java","javax.crypto.Mac")> 
    <cfset key = key.init(keyBytes,"HmacSHA512")> 
    <cfset mac = mac.getInstance(key.getAlgorithm())> 
    <cfset mac.init(key)> 
    <cfset mac.update(messageBytes)> 

    <cfreturn mac.doFinal()> 
</cffunction> 
+0

Çok teşekkür ederim Leigh! Yüzlerce kez başarısızlıktan sonra gerçek verilere ulaştığımı gördüğümde hissettiklerimi anlatabilmeyi isterdim. Asla işe yaramayacakmış gibi görünüyordu. Sen gerçek bir hayat kurtarıcısın! Teşekkürler teşekkürler teşekkürler! Bu web sitesinde dolaşmaya gidiyorum ve bunu ödemek için elimden geleni yapacağım. Namaste arkadaşım – Jay

+0

Yardımına sevindim! (Yeni api tuşları üretmeyi unutmayın :) – Leigh

+0

Sadece bu kadar zor bir soruyu cevaplamak için puan vermek için buraya geldim. –

İlgili konular