You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#调用Kraken API提示无效密钥但密钥合法的问题求助

C#调用Kraken API返回"Invalid Key"错误排查与解决

我使用C#调用Kraken的账户余额查询API时,确认API密钥合法,但始终收到"Invalid Key"错误响应,急需解决该问题。

核心实现代码

1. 创建API请求URL

var url = "https://api.kraken.com/0/private/Balance";

2. 创建请求对象

var request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";

3. 添加API密钥请求头

string apiKey = "API KEY";
request.Headers.Add("API-Key", apiKey);

4. 生成签名并添加请求头

string secret = "API SIGN";
var nonce = GenerateNonce();
var postData = $"nonce={nonce}";
var apiSign = ComputeSignature(url, nonce, postData, secret);
request.Headers.Add("API-Sign", apiSign);

5. 写入POST请求体

byte[] byteArray = Encoding.UTF8.GetBytes(postData);
request.ContentLength = byteArray.Length;
using (Stream dataStream = request.GetRequestStream())
{
    dataStream.Write(byteArray, 0, byteArray.Length);
}

6. 获取响应与错误处理

try
{
    using (var response = (HttpWebResponse)request.GetResponse())
    {
        using (var reader = new StreamReader(response.GetResponseStream()))
        {
            var responseString = reader.ReadToEnd();
            Console.WriteLine(responseString);
        }
    }
}
catch (WebException ex)
{
    using (var errorResponse = (HttpWebResponse)ex.Response)
    {
        using (var reader = new StreamReader(errorResponse.GetResponseStream()))
        {
            var error = reader.ReadToEnd();
            Console.WriteLine(error);
        }
    }
}

7. 辅助方法(原实现)

static string ComputeSignature(string url, string nonce, string postData, string secret)
{
    var path = new Uri(url).AbsolutePath;
    var data = Encoding.UTF8.GetBytes(nonce + postData);
    using (var hmac = new HMACSHA512(Convert.FromBase64String(secret)))
    {
        var pathBytes = Encoding.UTF8.GetBytes(path);
        hmac.TransformBlock(pathBytes, 0, pathBytes.Length, pathBytes, 0);
        hmac.TransformFinalBlock(data, 0, data.Length);
        var hash = hmac.Hash;
        var signature = Convert.ToBase64String(hash);
        return signature;
    }
}

static string GenerateNonce()
{
    var nonce = DateTime.UtcNow.Ticks;
    return nonce.ToString();
}

尝试过的其他哈希方法

public static byte[] ComputeSha256Hash(string nonce, string inputParams)
{
    string combinedString = nonce + inputParams;
    byte[] data = Encoding.UTF8.GetBytes(combinedString);

    using (SHA256 sha256Hash = SHA256.Create())
    {
        byte[] hashBytes = sha256Hash.ComputeHash(data);
        return hashBytes;
    }
}

public static byte[] ComputeSha512Hash(byte[] sha256Hash, string endpointName)
{
    byte[] endpointBytes = Encoding.UTF8.GetBytes(endpointName);
    byte[] combinedBytes = new byte[sha256Hash.Length + endpointBytes.Length];

    Buffer.BlockCopy(sha256Hash, 0, combinedBytes, 0, sha256Hash.Length);
    Buffer.BlockCopy(endpointBytes, 0, combinedBytes, sha256Hash.Length, endpointBytes.Length);

    using (SHA512 sha512Hash = SHA512.Create())
    {
        byte[] hashBytes = sha512Hash.ComputeHash(combinedBytes);
        return hashBytes;
    }
}

问题排查与修正方案

Kraken API的签名生成逻辑有严格要求,原实现的ComputeSignature方法不符合规范,这是导致"Invalid Key"的核心原因。正确的签名生成步骤如下:

  1. 对nonce + postData的字符串计算SHA-256哈希,得到字节数组。
  2. 将API的路径(如/0/private/Balance)的字节数组,与步骤1得到的SHA-256哈希字节数组合并。
  3. 使用Base64解码后的API密钥(secret)作为密钥,对合并后的字节数组计算HMAC-SHA512哈希。
  4. 将最终的HMAC哈希结果转换为Base64字符串,即为合法的API-Sign值。

修正后的签名计算方法

static string ComputeSignature(string url, string nonce, string postData, string secret)
{
    // 1. 获取API路径
    var path = new Uri(url).AbsolutePath;
    var pathBytes = Encoding.UTF8.GetBytes(path);

    // 2. 计算nonce+postData的SHA256哈希
    var noncePostDataBytes = Encoding.UTF8.GetBytes(nonce + postData);
    byte[] sha256Hash;
    using (var sha256 = SHA256.Create())
    {
        sha256Hash = sha256.ComputeHash(noncePostDataBytes);
    }

    // 3. 合并路径字节与SHA256哈希字节
    var combinedBytes = new byte[pathBytes.Length + sha256Hash.Length];
    Buffer.BlockCopy(pathBytes, 0, combinedBytes, 0, pathBytes.Length);
    Buffer.BlockCopy(sha256Hash, 0, combinedBytes, pathBytes.Length, sha256Hash.Length);

    // 4. 计算HMAC-SHA512并转Base64
    using (var hmac = new HMACSHA512(Convert.FromBase64String(secret)))
    {
        var hmacHash = hmac.ComputeHash(combinedBytes);
        return Convert.ToBase64String(hmacHash);
    }
}

其他注意事项

  • Nonce的有效性:确保nonce是严格递增的数值,且不能重复。原实现用DateTime.UtcNow.Ticks是可行的,但需注意避免同一毫秒内生成重复值(可在末尾追加随机数)。
  • 请求头规范:确认API-Key和API-Sign的拼写完全正确,大小写敏感。
  • 密钥正确性:再次验证API密钥和Secret是否从Kraken后台正确复制,没有多余空格或换行。

推荐NuGet包

如果不想手动实现签名逻辑,推荐使用成熟的第三方库:

  • Kraken.Net:专门针对Kraken API的.NET客户端,封装了所有签名、请求逻辑,支持同步/异步调用。
  • CryptoExchange.Net:包含Kraken.Net在内的多个交易所API客户端的基础库,提供统一的接口规范。

内容的提问来源于stack exchange,提问作者style

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 15:42:04