Saltar al contenido principal

Qué comprueba el firmante antes de firmar

Un código QR procedente de un dispositivo conectado es una entrada no fiable. BitTool Signer trata cada solicitud como potencialmente hostil y ejecuta el mismo proceso para todas las cadenas:

Decodificar y revisarSin contraseña
Autorizar y firmarContraseña en cada tarea
  1. 1Reúne los fotogramas QR y decodifica la solicitud de forma estricta (CBOR, PSBT, bytes de la transacción).
  2. 2Analiza los bytes exactos que se van a firmar y prepara la revisión: importes, destinatarios, comisiones, llamadas a contratos, advertencias.
  3. 3Asocia la solicitud a una cartera local usando solo claves públicas y fija un plan de firma vinculado al hash de la solicitud.
  4. el usuario revisa, confirma los riesgos e introduce la contraseña ▶
  5. 4Vuelve a derivar las claves a partir de la semilla y las contrasta con el plan antes de usarlas.
  6. 5Firma, verifica la nueva firma y codifica la respuesta en el mismo formato que la solicitud.

Decodificación estricta​

Antes de que se ejecute cualquier lógica específica de la cadena, se valida el transporte:

  • El CBOR debe usar longitudes definidas, sin claves de mapa duplicadas, sin bytes sobrantes al final, con un máximo de 24 niveles y 20 000 elementos. Se rechazan los campos de solicitud desconocidos.
  • Los códigos QR animados deben proceder de una sola sesión. Mezclar fotogramas de dos solicitudes es un error, no una fusión.
  • Límites de tamaño: 2048 fotogramas, 4300 caracteres por fotograma, 1 MiB de texto escaneado y 128 KiB de carga útil decodificada.

Los bytes CBOR (o PSBT) originales permanecen asociados a la solicitud decodificada. Justo antes de firmar, el motor los vuelve a decodificar y se niega a firmar si ya no coinciden con lo que se revisó.

La revisión muestra los bytes reales​

El motor analiza la transacción o el mensaje por sí mismo; nunca se fía de los resúmenes que proporciona la cartera en línea. Por ejemplo:

  • Bitcoin: cada entrada y salida con su importe y dirección, la comisión y qué salida es el cambio. Una salida solo cuenta como cambio si el firmante vuelve a derivar su script a partir de sus propias claves públicas. Las etiquetas del PSBT por sí solas nunca convierten una salida en «cambio».
  • EVM: red, nonce, comisiones, destinatario, valor nativo y llamadas decodificadas (transferencias y aprobaciones ERC-20/721/1155, Permit, Permit2, transacciones de Safe y más). Las direcciones de spender y de operator se comparan con una lista incluida de contratos públicos conocidos; un spender desconocido eleva el nivel de riesgo.
  • TRON: tipo de contrato, importes, llamadas TRC-20/721, límite de comisión, ID de permiso.
  • Solana: todas las instrucciones que conoce (System, SPL Token, Token-2022, ATA, Compute Budget, Memo, Stake y programas de NFT), el pagador de la comisión y los firmantes.

Cada solicitud recibe dos etiquetas independientes:

DecodificaciónRiesgo
Totalmente decodificada · Parcialmente decodificada · OpacaNormal · Advertencia · Alto

Una solicitud válida pero no totalmente decodificada (por ejemplo, una llamada a un contrato desconocido) se puede firmar igualmente, pero solo después de que el usuario acepte explícitamente el riesgo para esa solicitud. No existe ningún ajuste de «firma a ciegas» que quede activado. Los bytes mal formados, los tipos de transacción no compatibles y los datos de red contradictorios se rechazan directamente y no se pueden forzar.

Problemas conocidos en 1.0.0

Salvo que se indique lo contrario, están en el motor que comparten ambas apps. Consulta Revisiones de seguridad.

  • Confirmación del riesgo (BTS-OP5-01 en iPhone, BTS-12 en Android, Baja). Las solicitudes de riesgo alto totalmente decodificadas, como una aprobación ilimitada o setApprovalForAll, también necesitan la confirmación explícita, pero esa regla la impone la interfaz de la app (el botón Firmar sigue desactivado); el motor solo la impone en solicitudes parcialmente decodificadas u opacas. No se puede evitar desde un código QR.
  • Resúmenes de Solana (BTS-07, Media). Un cambio de autoridad, una delegación o una instrucción opaca enviados junto con una transferencia diminuta se resumen como esa transferencia. En iPhone 1.0.0 una quema puede ocultarse de la misma forma. Las advertencias y la confirmación se mantienen.
  • Cambio de Bitcoin (BTS-08, Media). Una salida cuenta como cambio en cualquier índice de los perfiles de firma única de la propia cartera, incluidos índices que una cartera de solo lectura nunca revisará.
  • Resúmenes de EVM y TRON (BTS-09, Baja–Media). El resumen guardado omite el valor nativo enviado con una llamada a un contrato desconocido; la tarjeta de revisión sí lo muestra.

Identificar la cartera correcta​

El usuario nunca elige qué cartera firma. El motor compara la solicitud con los datos públicos de cada cartera local y acepta exactamente una coincidencia:

CadenaDatos que se usan
BitcoinHuella y ruta de bip32Derivation, contrastadas con el script real de la entrada. Sin datos de derivación, solo se prueba /0/0 de cada cuenta de firma única.
EVMRuta de derivación (+ huella maestra) y/o dirección. Sin ruta, solo se compara el índice 0.
TRONRuta de derivación (cualquier índice), o una dirección comparada con los índices 0–99.
SolanaUna de las tres claves predefinidas, que además debe ocupar una posición de firmante obligatorio en el mensaje.

Que no haya coincidencia, que falte el firmante, que la coincidencia sea ambigua (encajan dos carteras) y que los datos de la cartera estén incompletos son errores distintos. El firmante nunca prueba la semilla de todas las carteras.

El resultado es un plan inmutable que vincula el hash canónico de la solicitud, los bytes originales, los bytes exactos que se firman y las claves y entradas de destino. Después de introducir la contraseña, el motor vuelve a derivar las claves, reconstruye los datos públicos, repite la asociación y compara el plan completo antes de tocar ninguna clave privada.

Qué significa esto para tu integración

Incluye siempre los datos de derivación: bip32Derivation en los PSBT, y la ruta y la huella en eth-, tron- y sol-sign-request. Las solicitudes con los datos completos del firmante se asocian de inmediato; las que no los tienen recurren al índice 0 y pueden fallar con cualquier otra cuenta.

Vincular la firma a la solicitud​

  • El motor calcula el hash de toda la solicitud canónica, firma, verifica su propia firma y devuelve el resultado junto con el hash de la solicitud original. Si el usuario sale de la app o una solicitud nueva sustituye a la anterior mientras se firma, el resultado que llegue tarde se descarta.
  • Las respuestas de EVM, TRON y Solana devuelven el ID de solicitud, y la firma cubre los bytes exactos que se revisaron. Las respuestas de Bitcoin devuelven el mismo PSBT con las firmas añadidas; todos los demás campos deben permanecer sin cambios.
  • Un PSBT puede necesitar varias carteras locales (una multifirma con dos claves en el mismo móvil). Cada cartera es una tarea independiente con su propia contraseña, y las firmas parciales se conservan entre tareas.

Las dos revisiones de seguridad de la versión 1.0.0 comprobaron esta cadena. La revisión de Opus 5 confirmó mediante ejecución que un plan manipulado se rechaza y que, en las compilaciones Release, el único punto de entrada para firmar pasa por todas estas comprobaciones.

Qué queda fuera del alcance sin conexión​

La revisión lo indica explícitamente cuando no puede saber algo: el comportamiento del contrato de un token, los saldos y las autorizaciones actuales, si un miembro de una multifirma de TRON sigue autorizado, si un blockhash de Solana sigue siendo válido o con qué se compromete realmente una raíz de Merkle de Blur. Tu cartera, que está en línea, está en mejor posición para mostrar ese contexto antes de crear el código QR.