2012-10-16 27 views
14

tôi đang cố gắng để thực hiện một yêu cầu ký hợp đồng với các API giao dịch tại bitfloor.com (đó là một API REST) ​​Coldfusion CFHTTP với SHA512-HMAC ký REST của yêu cầu cơ thể

Bitfloor mang lại cho tôi:

1) API Key (tức là 6bd2b780-00be-11e2-bde3-2837371c3c3a)

2) bí mật quan trọng (ví dụ oaFz62YpmbWiXwseMUSod53D8pOjdyVcweNYdiab/TSQqxk6IuemDvimNaQoA ==)

sau đây là hướng dẫn chính xác Bitfloor cho đưa ra yêu cầu:

Yêu cầu phải là yêu cầu HTTPS POST trên cổng 443 (https). Mỗi yêu cầu phải chứa các tiêu đề bắt buộc (được liệt kê bên dưới). Tiêu đề xác định, xác minh và xác thực yêu cầu của bạn để ngăn chặn giả mạo. tiêu đề

bitfloor-key Điều này được cung cấp bởi bitfloor để nhận dạng duy nhất tài khoản của bạn. (Ví dụ: 6bd2b780-00be-11e2-bde3-2837371c3c3a)

bitfloor-dấu Trường dấu là SHA512-HMAC của cơ thể yêu cầu bằng cách sử dụng khóa bí mật tương ứng với khóa API của bạn.

Để ký yêu cầu của bạn: base64 giải mã khóa bí mật thành byte thô (64 byte). Sử dụng các byte đó để ký sha512-hmac của bạn với phần thân yêu cầu http. Base64 mã hóa kết quả ký và gửi trong trường tiêu đề này.

bitfloor-passphrase Cụm mật khẩu bạn chỉ định khi tạo khóa api này. Chúng tôi không thể khôi phục cụm mật khẩu của bạn nếu bị lãng quên. Bạn sẽ cần tạo khóa API mới.

bitfloor phiên bản Phiên bản api của tài nguyên bạn đang quan tâm. Các giá trị hợp lệ duy nhất hiện nay là 1


Sau một tám đầy đủ giờ thử và sai và tìm kiếm trên internet nhiều lần đối với bất kỳ loại thông tin chi tiết hoặc thông tin, mã sau gần như tôi có thể đến những gì tôi nghĩ có thể ở đâu đó theo hướng làm thế nào để xây dựng yêu cầu đúng, than ôi, bất kể tôi đạt được gì API.

Dưới đây là những gì tôi có cho đến nay ...

FIRST, tôi thấy chức năng này trên web mà ai đó đã viết để làm việc ký kết SHA512:

<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> 

Tôi không có ý tưởng những gì nó làm , nhưng có vẻ như nó hoạt động và không có lỗi.

Đây là việc thực hiện chức năng này và nỗ lực của tôi khi thực hiện yêu cầu: LƯU Ý: Giá trị "nonce" là thông số bắt buộc phải được gửi cùng với yêu cầu.

<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> 

Tôi nghĩ hầu hết sự nhầm lẫn của tôi đến từ việc không biết chính xác "cơ thể yêu cầu" là gì. Tôi cảm thấy như tôi không ký điều đúng.

Tôi hy vọng có một lập trình viên Coldfusion ở đó, những người quen thuộc với các yêu cầu đã ký. Tôi đã tới giới hạn của mình rồi.

Vui lòng trợ giúp! Namaste

Trả lời

2

tôi chưa sử dụng api, nhưng tôi chạy một số xét nghiệm và có vẻ như để làm việc với các tinh chỉnh như sau:

  • Kể từ khi giá trị secretKey được mã hóa base64, chức năng ký của bạn cần phải sử dụng binaryDecode để trích xuất đúng byte. Sử dụng String.getBytes(...) sẽ tạo ra kết quả hoàn toàn khác (và sai).

  • Giá trị yêu cầu cơ thể kỳ vọng chỉ là: nonce=#nonceValue# (không có "?" hàng đầu)

  • Nó dường như đòi hỏi sự Content-Type=application/x-www-form-urlencoded tiêu đề, nếu không nó không phân tích nội dung và câu trả lời là: { "lỗi": "không nonce quy định"}

<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

Cảm ơn bạn rất nhiều Leigh! Tôi ước tôi có thể giải thích cho bạn về sự phấn khích mà tôi cảm thấy khi tôi nhìn thấy dữ liệu thực sự đã quay trở lại sau hàng trăm lần thất bại. Có vẻ như nó sẽ không bao giờ hoạt động. Bạn là một người tiết kiệm cuộc sống thực! Cảm ơn bạn, cảm ơn bạn, cảm ơn bạn! Tôi sẽ đi xung quanh trên trang web này và cố gắng hết sức để trả nó về phía trước. Namaste bạn của tôi – Jay

+0

Vui vì nó đã giúp! (Đừng quên tạo ra các khóa api mới :) – Leigh

+0

Chỉ cần đến đây để cung cấp cho bạn điểm để trả lời một câu hỏi khó như vậy. –

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