Las claves asimétricas implican el uso de dos claves: una clave privada y una clave pública, que son diferentes pero están vinculadas criptográficamente. La clave privada se usa para la generación de firmas, mientras que la clave pública se usa para la verificación de firmas. La clave de API la genera Deribit, pero el usuario genera el par de clave privada y clave pública. Deribit admite pares de claves Ed25519 o RSA. Deribit solo necesita usar la clave pública para la verificación de la firma, lo que permite que la clave privada
La principal ventaja del cifrado asimétrico radica en su modelo de seguridad mejorado, que separa las claves utilizadas para la generación de firmas y la verificación. Esta separación garantiza que, si bien los sistemas externos pueden autenticar las firmas para confirmar el origen y la integridad de los datos, son incapaces de generar firmas por sí mismos. Este atributo es crucial para mantener la seguridad y evitar el rechazo de los datos, ya que solo el titular de la clave privada puede originar las firmas
Además, el cifrado asimétrico proporciona una capa adicional de seguridad mediante la capacidad de agregar una contraseña a las claves privadas. Esto significa que, incluso si una entidad no autorizada accede de alguna manera a la clave privada, no se puede usar sin conocer también la contraseña
Tenga en cuenta que solo Autenticación de credenciales de Deribit Signature está disponible para claves API asimétricas.
Para crear un par de claves públicas y privadas, puede usar el script de Python que se proporciona más adelante o usar OpenSSL. OpenSSL es una biblioteca de software de código abierto que proporciona herramientas y bibliotecas para una comunicación segura e implementa los protocolos SSL y TLS para el cifrado, las funciones criptográficas
Compruebe si OpenSSL está instalado:
-
Abra la línea de comandos o PowerShell.
-
Escriba el siguiente comando y pulse Entrar:
openssl version -
Si OpenSSL está instalado, verá el número de versión. Si no es así, proceda a instalarlo
Instale OpenSSL:
-
Descargue el instalador desde este enlace.
-
Elija la versión adecuada para su sistema (Win32 o Win64).
-
Ejecute el instalador y siga las instrucciones.
Compruebe si OpenSSL está instalado:
-
Abra la terminal.
-
Escriba el siguiente comando y pulse Entrar:
openssl version -
Si OpenSSL está instalado, verá el número de versión. Si no es así, proceda a instalarlo
Instale OpenSSL:
-
Usa Homebrew para instalar OpenSSL. Si no tiene instalado Homebrew su sitio web oficial.
-
Una vez que Homebrew esté instalado, ejecuta:
brew install openssl -
Es posible que tengas que añadir OpenSSL a tu PATH. Siga las instrucciones dadas por Homebrew después de la instalación para hacerlo
Compruebe si OpenSSL está instalado:
-
Abra la terminal.
-
Escriba el siguiente comando y pulse Entrar:
openssl version -
Si OpenSSL está instalado, verá el número de versión. Si no es así, proceda a instalarlo
Instale OpenSSL:
Los comandos de instalación pueden variar según la distribución de Linux. Estos son los comandos de algunas distribuciones comunes
Debian/Ubuntu:
sudo apt update sudo apt install openssl
Fedora:
sudo dnf install openssl
Arch Linux:
sudo pacman -S openssl
Ejecute el siguiente comando para generar una clave privada:
openssl genpkey -algorithm ed25519 -out private.pem
Asegúrese de tener instalada la criptografía: - pip install cryptography
Generador de claves Ed25519 público y privado
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from cryptography.hazmat.primitives import serialization
private_key = Ed25519PrivateKey.generate()
private_pem = private_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.NoEncryption()
)
with open('private.pem', 'wb') as private_pem_file:
private_pem_file.write(private_pem)
public_key = private_key.public_key()
public_pem = public_key.public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo
)
with open('public.pem', 'wb') as public_pem_file:
public_pem_file.write(public_pem)
Generador de claves RSA públicas y privadas
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization
# Generate RSA private key
private_key = rsa.generate_private_key(
public_exponent=65537,
key_size=2048
)
# Serialize the private key to PEM format
private_pem = private_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.NoEncryption()
)
# Write the private key to a file
with open('private.pem', 'wb') as private_pem_file:
private_pem_file.write(private_pem)
# Get the corresponding public key
public_key = private_key.public_key()
# Serialize the public key to PEM format
public_pem = public_key.public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo
)
# Write the public key to a file
with open('public.pem', 'wb') as public_pem_file:
public_pem_file.write(public_pem)
Puede crear una nueva clave de API de Deribit mediante la interfaz de usuario o mediante la API de Deribit. Si quieres utilizar la API, consulta Cómo crear la clave de API asimétrica mediante la
Presiona 'Añadir nueva clave'en el lado derecho de la interfaz.
Seleccione Clave autogenerada y proporcione la clave pública generada anteriormente.
Importante
Pegue todo el contenido del archivo de clave pública, no solo el hash de base64. La clave pública debe incluir el encabezado -----BEGIN PUBLIC KEY-----, los datos de la clave codificada en base64 y el pie de página -----END PUBLIC KEY
Declare los alcances y otros detalles de la clave de la API:
-
Ámbitos: Describe el acceso máximo para la autorización con una clave determinada. Por favor, diríjase documentación oficial para obtener más detalles.
-
Campo de nombre: Se trata de una entrada personalizada que puede introducir para utilizarla como identificador de la clave.
-
Campo de características: Funciones opcionales adicionales relacionadas con esta clave de API. Es posible que se amplíen en versiones futuras.
-
Lista blanca de IP: Como característica de seguridad adicional, este campo restringe las direcciones IP que pueden conectarse mediante esta IP.
Una vez creado, recibirás ID de cliente
ID de cliente:El ID de cliente es un identificador público de la clave de API. No es un secreto. Puede quedar expuesto en los navegadores web, en el código fuente o en cualquier otro lugar sin problemas de seguridad inmediatos. Se usa principalmente para identificar la clave y no se usa por sí solo para la autenticación.
Registro de claves mediante la clave pública mediante private/create_api_key:
Solicitud
{
"method": "private/create_api_key",
"params": {
"public_key": "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEA/pQXmQa6m5NigEfu0UrbjDdzRORWYRluJasNiZau2Lo=\n-----END PUBLIC KEY-----",
"name": "ed25519key",
"max_scope": "account:read trade:read_write wallet:read"
},
"jsonrpc": "2.0",
"id": 1
}
Respuesta
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"max_scope": "trade:read_write wallet:read account:read",
"ip_whitelist": [],
"client_secret": "81:c2:76:35:a7:1a:1c:f8:05:71:e1:42:7c:94:2c:4c",
"client_id": "GgUXjYUj",
"enabled_features": [],
"public_key": "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEA/pQXmQa6m5NigEfu0UrbjDdzRORWYRluJasNiZau2Lo=\n-----END PUBLIC KEY-----",
"timestamp": 1721816749587,
"name": "ed25519key",
"id": 11,
"enabled": true,
"default": false
}
}
Solo Firma de Deribit: autenticación de credenciales está disponible para claves API asimétricas. Para autenticarse con una clave API asimétrica, la firma debe estar firmada con una clave privada. A continuación, se muestran ejemplos de cómo firmar la firma mediante comandos de shell y código Python
base_url=
timestamp=$( date +%s000 )
nonce=$( cat /dev/urandom | tr -dc 'a-z0-9' | head -c8 )
verb=GET
uri='/api/v2/private/get_current_deposit_address?currency=eth'
datatosign=$(mktemp)
echo -ne "${timestamp}\n${nonce}\n${verb}\n${uri}\n\n" > ${datatosign}
# client_id received when creating the API key
client_id=xyz
signature=$(openssl pkeyutl -sign -inkey private.pem -rawin -in ${datatosign} | base64 -w 100 | sed 's#+#-#g;s#/#_#g;s#=##g')
rm ${datatosign}
curl -s -X ${verb} -H "Authorization: DERI-HMAC-SHA256 id=${client_id},ts=${timestamp},nonce=${nonce},sig=${signature}" "${base_url}${uri}" | jq
Autenticación Ed25519
import asyncio
from cryptography.hazmat.primitives import serialization
import websockets
import base64
import json
from datetime import datetime
# client_id received when creating the API key
client_id='xyz'
with open('private.pem', 'rb') as private_pem:
private_key = serialization.load_pem_private_key(private_pem.read(), password=None)
timestamp = round(datetime.now().timestamp() * 1000)
nonce = "abcd"
data = ""
data_to_sign = bytes('{}\n{}\n{}'.format(timestamp, nonce, data), "latin-1")
signature = base64.urlsafe_b64encode(private_key.sign(data_to_sign)).decode('utf-8').rstrip('=')
msg = {
"jsonrpc": "2.0",
"id": 1,
"method": "public/auth",
"params": {
"grant_type": "client_signature",
"client_id": client_id,
"timestamp": timestamp,
"signature": signature,
"nonce": nonce,
"data": data
}
}
async def call_api(msg):
async with websockets.connect('wss://test.deribit.com/ws/api/v2') as websocket:
await websocket.send(msg)
while websocket.open:
response = await websocket.recv()
# do something with the response...
print(response)
await websocket.send(json.dumps({
"jsonrpc": "2.0",
"id": 2,
"method": "private/get_positions",
"params": {
"currency": "btc"
}
}))
response = await websocket.recv()
print(response)
exit()
asyncio.get_event_loop().run_until_complete(call_api(json.dumps(msg)))
Autenticación RSA
import asyncio
from cryptography.hazmat.primitives import serialization, hashes
from cryptography.hazmat.primitives.asymmetric import padding
import websockets
import base64
import json
from datetime import datetime
# client_id received when creating the API key
client_id = 'xyz'
# Load the private key from the PEM file
with open('private.pem', 'rb') as private_pem:
private_key = serialization.load_pem_private_key(private_pem.read(), password=None)
# Generate timestamp, nonce, and data to sign
timestamp = round(datetime.now().timestamp() * 1000)
nonce = "abcd"
data = ""
# Prepare the data to sign
data_to_sign = bytes('{}\n{}\n{}'.format(timestamp, nonce, data), "latin-1")
# Sign the data using the RSA private key with padding and hashing algorithm
signature = private_key.sign(
data_to_sign,
padding.PKCS1v15(),
hashes.SHA256()
)
# Encode the signature to base64
encoded_signature = base64.urlsafe_b64encode(signature).decode('utf-8').rstrip('=')
# Prepare the message
msg = {
"jsonrpc": "2.0",
"id": 1,
"method": "public/auth",
"params": {
"grant_type": "client_signature",
"client_id": client_id,
"timestamp": timestamp,
"signature": encoded_signature,
"nonce": nonce,
"data": data
}
}
# Function to call the API
async def call_api(msg):
async with websockets.connect('wss://test.deribit.com/ws/api/v2') as websocket:
await websocket.send(msg)
while websocket.open:
response = await websocket.recv()
# do something with the response...
print(response)
await websocket.send(json.dumps({
"jsonrpc": "2.0",
"id": 2,
"method": "private/get_positions",
"params": {
"currency": "btc"
}
}))
response = await websocket.recv()
print(response)
exit()
# Run the event loop to call the API
asyncio.get_event_loop().run_until_complete(call_api(json.dumps(msg)))
-
¿Puedo usar varias teclas asimétricas?
Sí, puede crear y administrar varias claves asimétricas para diferentes aplicaciones o sistemas.
-
¿Qué debo hacer si mi clave privada está comprometida?
Revoca inmediatamente la clave pública correspondiente de tu cuenta de Deribit y genera un nuevo par de claves.
-
¿Siguen siendo necesarios los alcances y los permisos para las claves asimétricas?
Sí, debes asignar datos específicos alcances (permisos) al crear una clave de API, al igual que con las credenciales de API estándar.