Punca Biasa Ralat Kunci Tidak Sah

Terakhir dikemas kini: 5 Jun 2025

Untuk membuat panggilan peribadi yang berjaya, permintaan HTTP POST perlu dihantar ke titik akhir yang sesuai.

Permintaan ini termasuk Pengepala API-Sign (tandatangan) yang menggunakan Post_data yang dikodkan sebagai sebahagian daripada algoritma hashingnya.

Jika terdapat percanggahan antara Tandatangan yang disertakan dalam pengepala dan data POST yang disertakan dalam permintaan, ralat Kunci API Tidak Sah akan dikembalikan.

Di bawah adalah contoh panggilan yang dirumuskan dengan betul di mana data yang digunakan dalam Algoritma Pengesahan sepadan dengan yang terdapat dalam badan permintaan:

python

Python

#!/usr/bin/env python3

import time
import requests
import urllib.parse
import hashlib
import hmac
import base64

api_key = ''
secret_key = ''
nonce = str(int(1000 * time.time()))

# Define the URI path for the Kraken API request
uri_path = '/0/private/AddOrder'

# API URL
api_url = 'https://api.kraken.com'

# Create a dictionary for the request data
# Note that this is the data that will be used to calculate the Authentication Algorithm (API-Sign).
data = {
    'nonce': nonce,
    'ordertype': 'limit',
    'type': 'buy',
    'volume': '1',
    'pair': 'btcusd',
    'price': '58626.4',
    'validate': True
}

# Encode the data for the request
postdata = urllib.parse.urlencode(data)
encoded = (str(data['nonce']) + postdata).encode()

# Create a message to be signed
message = uri_path.encode() + hashlib.sha256(encoded).digest()

# Create the HMAC signature
mac = hmac.new(base64.b64decode(secret_key), message, hashlib.sha512)
sigdigest = base64.b64encode(mac.digest())

# Create headers for the request
headers = {}
headers['API-Key'] = api_key
headers['API-Sign'] = sigdigest.decode()

# Make the POST request
# Note that the data below is what is sent in the HTTP request.
req = requests.post(api_url + uri_path, headers=headers, data={
    'nonce': nonce,
    'ordertype': 'limit',
    'type': 'buy',
    'volume': '1',
    'pair': 'btcusd',
    'price': '58626.4',
    'validate': True
})

# Print the result
print(req.json())

# Result:
# {'error': [], 'result': {'descr': {'order': 'buy 1.00000000 XBTUSD @ limit 58626.4'}}}

Walau bagaimanapun, apabila ordertype dan volume ditukar ganti, ralat Kunci Tidak Sah dihasilkan.

python

Python

#!/usr/bin/env python3
import time
import requests
import urllib.parse
import hashlib
import hmac
import base64

api_key = ''
secret_key = ''
nonce = str(int(1000 * time.time()))

# Define the URI path for the Kraken API request
uri_path = '/0/private/AddOrder'

# API URL
api_url = 'https://api.kraken.com'

# Create a dictionary for the request data
data = {
    'nonce': nonce,
    'ordertype': 'limit',
    'type': 'buy',
    'volume': '1',
    'pair': 'btcusd',
    'price': '58626.4',
    'validate': True
}

# Encode the data for the request
postdata = urllib.parse.urlencode(data)
encoded = (str(data['nonce']) + postdata).encode()

# Create a message to be signed
message = uri_path.encode() + hashlib.sha256(encoded).digest()

# Create the HMAC signature
mac = hmac.new(base64.b64decode(secret_key), message, hashlib.sha512)
sigdigest = base64.b64encode(mac.digest())

# Create headers for the request
headers = {}
headers['API-Key'] = api_key
headers['API-Sign'] = sigdigest.decode()

# Make the POST request
req = requests.post(api_url + uri_path, headers=headers, data={
    'nonce': nonce,
    'volume': '1',
    'type': 'buy',
    'ordertype': 'limit',
    'volume': '1',
    'pair': 'btcusd',
    'price': '58626.4',
    'validate': True
})

# Print the result
print(req.json())

# Result:
# {'error': ['EAPI:Invalid key']}

Satu petunjuk bahawa ini mungkin punca ralat Kunci Tidak Sah adalah jika panggilan ke titik akhir yang tidak memerlukan pelbagai parameter berjaya (Balance, OpenOrders). Jika anda sentiasa mendapat respons yang sah daripada panggilan ini, maka teori ketidakpadanan kelihatan lebih munasabah.

*Sila ambil perhatian bahawa dalam contoh di atas, Parameter Sahkan digunakan yang hanya mengesahkan input sahaja tetapi tidak menyerahkan pesanan. Parameter tersebut harus dibuang untuk perdagangan langsung*

Mempunyai ketidakpadanan antara jenis kandungan badan dan pengepala juga boleh menyebabkan Kunci API Tidak Sah.

Sila lihat di bawah senario di mana kedua-dua Pengepala dan data Post dikodkan URL:

 

python

Python

api_key = ""

api_secret = base64.b64decode("")

api_domain = "https://api.kraken.com"
api_path = "/0/private/"
api_endpoint = "Balance"  # {"error":[]} IS SUCCESS-EMPTY BALANCE
api_parameters = ""

api_nonce = str(int(time.time() * 1000))

api_postdata = api_parameters + "&nonce=" + api_nonce
api_postdata = api_postdata.encode('utf-8')

api_sha256Data = api_nonce.encode('utf-8') + api_postdata
api_sha256 = hashlib.sha256(api_sha256Data).digest()

api_hmacSha512Data = api_path.encode('utf-8') + api_endpoint.encode('utf-8') + api_sha256
api_hmacsha512 = hmac.new(api_secret, api_hmacSha512Data, hashlib.sha512)

api_sig = base64.b64encode(api_hmacsha512.digest())

api_url = api_domain + api_path + api_endpoint
api_request = urllib2.Request(api_url, api_postdata)
api_request.add_header("Content-Type", "application/x-www-form-urlencoded")
api_request.add_header("API-Key", api_key)
api_request.add_header("API-Sign", api_sig)
api_request.add_header("User-Agent", "Kraken REST API")

print("DEBUG DATA : ")
print("api_url : " + api_url)
print("api_endpoint : " + api_endpoint)
print("api_parameters : " + api_parameters)

print("")

api_reply = urllib2.urlopen(api_request).read()
api_reply = api_reply.decode()

print("API JSON DATA:")
print(api_reply)

sys.exit(0)

# Response:
# API JSON DATA:
# {"error":[],"result":{"ADA":"0.00000000","AIR":"0.0000000000","ALGO":"0.00000000","ATOM":"0.00000000",
# "AVAX":"0.0000000000","BONK":"0.24","BSX":"0.00","C98":"0.00000","CVC":"0.0000000000","DOT":"0.0000000058",
# "DYM":"1.001240","ETH2.S":"0.0000000000","FLOW":"0.0000000000","FLR":"0.0000","GRT":"0.0000000000","ICP":"0.00000000",
# "KAVA":"0.00000000","KFEE":"4619.88","KSM":"0.0457969620","KSM.S":"0.0000000000","MATIC":"0.0000000000",
# "MINA":"1.0067624751","MINA.S":"0.0000000000","PARA":"0.000","POLS":"0.00000","SBR":"0.00000000","SCRT":"0.00000000",
# "SCRT21.S":"0.00000000","SDN":"0.0000000000","SEI":"0.0000","SHIB":"0.00000","SOL":"0.0000069748","SOL.S":"0.0000000000",
# "SOL03.S":"0.0201035317","TIA":"0.000000","TRX":"0.00000000","USDC":"0.00000000","USDT":"0.00068726",
# "USDT.B":"3.53191423","WEN":"158958.59","WIF":"0.00000","XBT.M":"0.0001000103","XETH":"0.0000000000",
# "XTZ":"0.00000000","XXBT":"0.0000000000","XXDG":"24.34451185","XXMR":"0.0000000000","ZCAD":"0.0000",
# "ZEUR":"0.2732","ZUSD":"0.6353"}}

Walau bagaimanapun, apabila kami menambah Jenis Kandungan Pengepala sebagai JSON, kami mendapat

EAPI:Ralat Kunci Tidak Sah.

 

python

Python

api_key = ""

api_secret = base64.b64decode("")

api_domain = "https://api.kraken.com"
api_path = "/0/private/"
api_endpoint = "AddOrder"  # {"error":[]} IS SUCCESS-EMPTY BALANCE

# api_parameters = "pair=xbtusd&ordertype=market&type=buy&volume=0.0001&validate=True"
api_parameters = ''

api_nonce = str(int(time.time() * 1000))

api_postdata = api_parameters + "&nonce=" + api_nonce
api_postdata = api_postdata.encode('utf-8')

api_sha256Data = api_nonce.encode('utf-8') + api_postdata
api_sha256 = hashlib.sha256(api_sha256Data).digest()

api_hmacSha512Data = api_path.encode('utf-8') + api_endpoint.encode('utf-8') + api_sha256
api_hmacsha512 = hmac.new(api_secret, api_hmacSha512Data, hashlib.sha512)

api_sig = base64.b64encode(api_hmacsha512.digest())

api_url = api_domain + api_path + api_endpoint
api_request = urllib2.Request(api_url, api_postdata)

print("DEBUG DATA : ")
print("api_url : " + api_url)
print("api_endpoint : " + api_endpoint)
print("api_parameters : " + api_parameters)
print("")

headers = {}
headers['API-Key'] = api_key
headers['API-Sign'] = api_sig
headers['Content-Type'] = 'application/json'
headers['Accepts'] = 'application/json'
headers['User-Agent'] = "Kraken REST API"

api_reply = urllib2.urlopen(api_request).read()
api_reply = api_reply.decode()

data = {'nonce': api_nonce}
req = requests.post(api_url, headers=headers, data=data)
print(req.json())

print("API JSON DATA:")
print(api_reply)

sys.exit(0)

# API JSON DATA:
# {"error":["EAPI:Invalid key"]}

*Ambil perhatian bahawa adalah mungkin untuk menggunakan data yang dikodkan URL atau data yang dikodkan JSON, tetapi data tersebut mesti sepadan dengan tepat dalam kedua-dua input SHA256 dan permintaan HTTP.*

Ralat Kunci Tidak Sah juga boleh disebabkan oleh penghantaran URI titik akhir yang tidak lengkap atau hilang (contohnya "AddOrder" berbanding “/0/private/AddOrder”).

Agar Algoritma Pengesahan dapat mencipta Pengepala API-Sign dengan betul, ia perlu menggunakan URI secara keseluruhannya (contohnya "/0/private/AddOrder”). Jika mana-mana bahagian URI ini dipotong, ia akan menyebabkan nilai yang salah untuk API-Sign dan seterusnya ralat Kunci Tidak Sah.

Di bawah adalah contoh hanya “AddOrder” dihantar untuk pengekodan dan bukannya URI titik akhir penuh “/0/private/AddOrder”

python

Python

api_key = ''
secret_key = ''

# Define the URI path for the Kraken API request
uri_path = 'AddOrder'

# API URL
api_url = 'https://api.kraken.com/0/private/'

# Create a dictionary for the request data
data = {
    "nonce": str(int(1000 * time.time())),
    "ordertype": 'limit',
    'type': 'buy',
    'volume': '0.07617478622420963',
    'pair': 'SOLUSD',
    'price': '127.47',
    'validate': 'true'
}

# Encode the data for the request
postdata = urllib.parse.urlencode(data)
encoded = (str(data['nonce']) + postdata).encode()

# Create a message to be signed
message = uri_path.encode() + hashlib.sha256(encoded).digest()

# Create the HMAC signature
mac = hmac.new(base64.b64decode(secret_key), message, hashlib.sha512)
sigdigest = base64.b64encode(mac.digest())

# Create headers for the request
headers = {}
headers['API-Key'] = api_key
headers['API-Sign'] = sigdigest.decode()

# Make the POST request
req = requests.post(api_url + uri_path, headers=headers, data=data)

# Print the result
print(req.json())

# Result:
# {'error': ['EAPI:Invalid key']}

Satu lagi isu biasa yang menyebabkan Ralat Kunci Tidak Sah adalah ketidakpadanan pengekodan antara permintaan POST dan pengesahan HTTP.

Dalam contoh di bawah, ‘Data’ yang dihantar ke permintaan POST diformatkan URL (dengan ruang dikodkan sebagai ‘+’) sebagai jenis kandungan application /x-www-form-urlencoded manakala ‘data_formatted’ mengekod ruang sebagai ‘%20’.

Walaupun dalam kedua-dua contoh ruang dikodkan, data yang dihantar ke algoritma pengesahan dan permintaan POST tidak sama persis. Ini akan menyebabkan ralat Kunci Tidak Sah.

 

python

Python

# Define the URI path for the Kraken API request
uri_path = '/0/private/DepositAddresses'

# API URL
api_url = 'https://api.kraken.com'

# Calculate Nonce for both data variables
nonce = str(int(1000 * time.time()))

# Create a dictionary for the request data
data = {
    "nonce": nonce,
    "asset": 'BTC',
    'method': 'Bitcoin Lightning',
    'amount': '0.2',
    'new': True
}

postdata_data = urllib.parse.urlencode(data)

# Encode the data for the request manually
data_formatted = f'nonce={nonce}&asset=BTC&method=Bitcoin%20Lightning&amount=0.2&new=True'
postdata = data_formatted
encoded = (nonce + postdata).encode()

# Create a message to be signed
message = uri_path.encode() + hashlib.sha256(encoded).digest()

# Create the HMAC signature
mac = hmac.new(base64.b64decode(secret_key), message, hashlib.sha512)
sigdigest = base64.b64encode(mac.digest())

# Create headers for the request
headers = {}
headers['API-Key'] = api_key
headers['API-Sign'] = sigdigest.decode()

# Make the POST request
req = requests.post(api_url + uri_path, headers=headers, data=data)

# Print the result
print(req.json())

# Result:
# {'error': ['EAPI:Invalid key']}

Untuk menggambarkan ini dengan jelas, sila lihat di bawah 2 format Data yang berbeza:

bash

Bash

data = nonce=1719929687102&asset=BTC&method=Bitcoin+Lightning&amount=0.2&new=True

data_formatted = nonce=1719929687102&asset=BTC&method=Bitcoin%20Lightning&amount=0.2&new=True

*Adalah mungkin untuk menggunakan teks biasa atau pengekodan peratus selagi formatnya sama dalam kedua-dua data Pengesahan dan permintaan.*

Perlu bantuan lebih lanjut?