简体   繁体   English

Coinbase FIX 登录签名

[英]Coinbase FIX Logon signature

Problem: I cannot properly encode signature, according to https://docs.cloud.coinbase.com/exchange/docs/messages .问题:根据https://docs.cloud.coinbase.com/exchange/docs/messages ,我无法正确编码签名。 No matter what I'm doing, I'm getting "Invalid signature" rejection.无论我在做什么,我都会收到“无效签名”的拒绝。

I'm using QuickFix FIX engine, and my code is written in C++.我正在使用 QuickFix FIX 引擎,我的代码是用 C++ 编写的。 Signature calculation code provided below.下面提供签名计算代码。 b64_encode and hmac_sha256 are based on OpenSSL functions and were verified in another parts of application, so they are expected to be working correctly (unless Coinbase actually expects another kind of encryption). b64_encode 和 hmac_sha256 基于 OpenSSL 函数,并在应用程序的其他部分进行了验证,因此预计它们可以正常工作(除非 Coinbase 实际上需要另一种加密)。

const auto join_elem = '\x01';
auto data_to_encrypt =
    header.getField(FIX::FIELD::SendingTime) + join_elem +
    "A" + join_elem +
    header.getField(FIX::FIELD::MsgSeqNum) + join_elem +
    header.getField(FIX::FIELD::SenderCompID) + join_elem +
    header.getField(FIX::FIELD::TargetCompID) + join_elem +
    api_password;

std::vector<unsigned char> prehash(data_to_encrypt.begin(), data_to_encrypt.end());
auto signature_value = b64_encode(hmac_sha256(data, b64_decode(secret)));

As I'm using sandbox account, it is safe to share all the keys for the case if someone could verify calculation.由于我使用的是沙箱帐户,因此如果有人可以验证计算,则可以安全地共享该案例的所有密钥。
api_password=uxu3qgheh0e api_password=uxu3qgheh0e
SenderCompID=b0744eb59b6951d7955e5e5aaed3709f发件人CompID=b0744eb59b6951d7955e5e5aaed3709f
secret=T/SabUfV28tyVDVv5AsMuk5oqDFdvGwQrfc6f1/RnatGfpAcpAMMRzjfON8nqoL6bAsUI6jkN9gWEX809z1iiA==秘密=T/SabUfV28tyVDVv5AsMuk5oqDFdvGwQrfc6f1/RnatGfpAcpAMMRzjfON8nqoL6bAsUI6jkN9gWEX809z1iiA==

Complete logon example:完整登录示例:
8=FIX.4.2|9=172|35=A|34=1|49=b0744eb59b6951d7955e5e5aaed3709f|52=20211112-16:45:45.856|56=Coinbase|96=6fsAC9XcV9Fm4II89s8VZgm4wmeiNclr3YY+mNTbMdo=|98=0|108=30|141=Y|554=uxu3qgheh0e|8013=Y|10=253| 8=FIX.4.2|9=172|35=A|34=1|49=b0744eb59b6951d7955e5e5aaed3709f|52=20211112-16:45:45.856|56=Coinbase|94XIIc80mFm=6V90FsM|94XIIc8V90FsM|96 |141=Y|554=uxu3qgheh0e|8013=Y|10=253|
And the following rejection:以及以下拒绝:
8=FIX.4.2|9=128|35=3|34=1|49=Coinbase|52=20211112-16:45:46.985|56=b0744eb59b6951d7955e5e5aaed3709f|45=1|58=invalid signature|371=96|372=A|373=5|10=216| 8=FIX.4.2|9=128|35=3|34=1|49=Coinbase|52=20211112-16:45:46.985|56=b0744eb59b6951d7955e5e5aaed3709f|45=1|3709f|47=1|365 =A|373=5|10=216|

Unfortunately, support replied with "Coinbase will only offer self-help customer support in your region", so I have to ask for help here.不幸的是,支持回复为“Coinbase 只会在您所在地区提供自助客户支持”,所以我不得不在这里寻求帮助。 Thanks!谢谢!

During a day of research, I finally found the issue.经过一天的研究,我终于找到了问题所在。 As I first step, I found working library written in NodeJS (it was easier to use it for testing) to ensure my credentials are working.作为我的第一步,我发现用 NodeJS 编写的工作库(使用它进行测试更容易)以确保我的凭据有效。 Then I added console prints to NodeJS lib to see what values are calculated on the each step of signature making.然后我将控制台打印添加到 NodeJS lib,以查看在签名制作的每个步骤中计算了哪些值。 Then I used the same values for my code and finally came to base64 decoding function, which I used to "decode" secret key.然后我对我的代码使用了相同的值,最后来到了 base64 解码函数,我用它来“解码”密钥。 It was the following:是这样的:

std::vector<unsigned char> b64_decode(const std::string& data) {
    BIO* b64 = BIO_new(BIO_f_base64());
    BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);

    BIO* bmem = BIO_new_mem_buf((void*)data.c_str(), data.length());
    bmem = BIO_push(b64, bmem);

    std::vector<unsigned char> output(data.length());
    int decoded_size = BIO_read(bmem, output.data(), output.size());
    BIO_free_all(bmem);

    return output;
}

This function appears to be incorrect if source data size not equal to output size, as I forgot to resize output according to actual length, and it was containing extra zeroes which caused decoded secret key to be incorrect.如果源数据大小不等于输出大小,则此函数似乎不正确,因为我忘记根据实际长度调整输出大小,并且它包含额外的零,导致解码的密钥不正确。 Ie I just needed to add resize:即我只需要添加调整大小:

if (output.size() > decoded_size) {
    output.resize(decoded_size);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM