Cómo abrir sesión en el SII con un certificado digital: semilla, firma y token
El flujo semilla → firma → token para autenticarte en los servicios web del SII, con el código en C#.
Para consumir los servicios web del Servicio de Impuestos Internos (SII) —enviar DTE, consultar el estado de un envío, etc.— primero necesitas autenticarte y obtener un token de sesión. Ese token se consigue en tres pasos: pides una semilla al SII, la firmas con tu certificado digital y la canjeas por un token.
Esta guía resume lo medular para lograrlo, con el código clave para firmar la semilla.
En resumen (TL;DR):
getSeed→ firmas la semilla (firma XML enveloped RSA‑SHA1 con tu certificado) →getToken→ usas el token en las siguientes peticiones (por ejemplo, en la cabeceraCookie: TOKEN=…).
🔐 ¿Aún no tienes certificado? ABANCERT emite certificados digitales de Firma Electrónica Simple compatibles con el SII, con solicitud 100 % en línea: Solicita tu certificado digital simple
1. Requisitos
- Un certificado digital vigente con clave privada (por ejemplo, un certificado de Firma
Electrónica Simple de ABANCERT).
Puede estar en un archivo
.pfx/.p12o instalado en el almacén de certificados de Windows. - El RUT del certificado habilitado ante el SII: el contribuyente debe haber autorizado a esa persona/certificado para operar la facturación electrónica. Si no, el SII rechazará el token.
- Un entorno capaz de hacer
POSTpor HTTPS (TLS 1.2+), armar mensajes SOAP y firmar XML con RSA‑SHA1. En .NET esto se logra conSystem.Security.Cryptography.Xml.SignedXml. - Conexión a los servidores del SII (certificación o producción).
2. Los servicios web de autenticación
El SII expone dos servicios SOAP para autenticación:
| Servicio | Certificación (pruebas · maullin) | Producción (palena) |
|---|---|---|
Semilla (CrSeed → getSeed) | https://maullin.sii.cl/DTEWS/CrSeed.jws | https://palena.sii.cl/DTEWS/CrSeed.jws |
Token (GetTokenFromSeed → getToken) | https://maullin.sii.cl/DTEWS/GetTokenFromSeed.jws | https://palena.sii.cl/DTEWS/GetTokenFromSeed.jws |
Son servicios SOAP estilo RPC, con SOAPAction vacío. getSeed() no recibe parámetros y
getToken(pszXml) recibe un único parámetro de tipo string (la semilla ya firmada). El valor que
devuelven es, a su vez, un XML de respuesta del SII.
3. El flujo en 3 pasos
Tu aplicación SII
| |
| 1) getSeed() ---------------> |
| <--------------- SEMILLA |
| |
| 2) firmas la semilla |
| con tu certificado |
| |
| 3) getToken(semillaFirmada) -> |
| <---------------- TOKEN |
| |
| 4) usas el TOKEN en las |
| siguientes peticiones ---> |
Paso 1 · Obtener la semilla (getSeed)
El SII responde con un XML como este:
<SII:RESPUESTA xmlns:SII="http://www.sii.cl/XMLSchema">
<SII:RESP_HDR>
<ESTADO>00</ESTADO>
</SII:RESP_HDR>
<SII:RESP_BODY>
<SEMILLA>0079009845665</SEMILLA>
</SII:RESP_BODY>
</SII:RESPUESTA>
La semilla es un número. Tiene vigencia corta: fírmala y pide el token de inmediato.
Paso 2 · Firmar la semilla (lo medular)
Debes construir este documento y firmarlo con tu certificado:
<getToken><item><Semilla>0079009845665</Semilla></item></getToken>
La firma es una firma XML enveloped (queda dentro del propio <getToken>), con algoritmo
RSA‑SHA1. Más abajo está el código.
Paso 3 · Obtener el token (getToken)
Envías el <getToken> firmado y el SII responde:
<SII:RESPUESTA xmlns:SII="http://www.sii.cl/XMLSchema">
<SII:RESP_HDR>
<ESTADO>00</ESTADO>
<GLOSA>Token Creado</GLOSA>
</SII:RESP_HDR>
<SII:RESP_BODY>
<TOKEN>ABCD1234EFGH</TOKEN>
</SII:RESP_BODY>
</SII:RESPUESTA>
4. Código: firmar la semilla (C# / .NET)
Este es el corazón del proceso: recibe la semilla y el certificado, y devuelve el <getToken>
firmado, listo para enviarse a getToken.
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography.Xml;
using System.Xml;
/// Firma la semilla del SII y devuelve el XML <getToken> firmado.
public static string FirmarSemilla(string semilla, X509Certificate2 certificado)
{
// 1) Documento que el SII espera firmar.
var documento = new XmlDocument { PreserveWhitespace = true };
documento.LoadXml(
$"<?xml version=\"1.0\"?><getToken><item><Semilla>{semilla}</Semilla></item></getToken>");
// 2) Clave privada RSA del certificado.
// GetRSAPrivateKey() funciona con claves CNG o CSP, vengan de un .pfx
// o del almacén de Windows: por eso el firmador es "a prueba de origen".
using var rsa = certificado.GetRSAPrivateKey()
?? throw new InvalidOperationException("El certificado no tiene clave privada RSA.");
// 3) Firma XML "enveloped" con algoritmos SHA-1 (los que valida el SII).
var firma = new SignedXml(documento) { SigningKey = rsa };
firma.SignedInfo!.SignatureMethod = SignedXml.XmlDsigRSASHA1Url; // rsa-sha1
firma.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigC14NTransformUrl; // c14n
var referencia = new Reference
{
Uri = "#xpointer(/)", // firma el documento completo
DigestMethod = SignedXml.XmlDsigSHA1Url // sha1
};
referencia.AddTransform(new XmlDsigEnvelopedSignatureTransform());
firma.AddReference(referencia);
// 4) KeyInfo: clave pública + certificado (el SII los usa para validar la firma).
var keyInfo = new KeyInfo();
keyInfo.AddClause(new RSAKeyValue(rsa));
keyInfo.AddClause(new KeyInfoX509Data(certificado));
firma.KeyInfo = keyInfo;
firma.ComputeSignature();
// 5) Inserta la firma dentro del <getToken> y devuelve el XML final.
documento.DocumentElement!.AppendChild(documento.ImportNode(firma.GetXml(), deep: true));
return documento.OuterXml;
}
Lo relevante al configurar el firmador
- Obtén la clave con
GetRSAPrivateKey(), no con la propiedad antiguaX509Certificate2.PrivateKey. Así funciona por igual con claves CNG o CSP y con certificados de archivo o del almacén de Windows. (En .NET Framework, usar la propiedad antigua suele provocar el error “Algoritmo especificado no es válido” al firmar;GetRSAPrivateKey()lo evita.) - Fija los algoritmos SHA‑1 explícitamente (
rsa-sha1ysha1). El SII valida SHA‑1; no dependas de los valores por defecto del framework, que pueden variar entre versiones. PreserveWhitespace = true: si el documento se re‑formatea después de firmar, la firma deja de ser válida. Mantén el XML intacto.Uri = "#xpointer(/)"+ transformación enveloped: firma todo el documento y deja la firma dentro de<getToken>.- Incluye el certificado en
KeyInfo(KeyInfoX509Data): el SII lo necesita para validar la firma y verificar la identidad del firmante.
Encapsula la obtención del certificado (archivo
.pfxo almacén de Windows) por separado y entrega siempre unX509Certificate2con clave privada. Así el firmador no cambia según el origen del certificado.
5. Respuestas del SII: cómo interpretarlas
La clave está en el nodo ESTADO de RESP_HDR:
ESTADO=00→ éxito. La semilla viene enRESP_BODY/SEMILLAy el token enRESP_BODY/TOKEN.ESTADOdistinto de00→ error. El detalle viene enGLOSA.
Causas frecuentes de rechazo al pedir el token:
- Semilla vencida: pasó demasiado tiempo entre
getSeedygetToken. Repite el flujo. - Firma inválida: algoritmo distinto de SHA‑1, XML alterado tras firmar, o falta el certificado en
KeyInfo. - Certificado o RUT sin autorización: el RUT del certificado no está habilitado por el contribuyente para facturación electrónica en ese ambiente (certificación vs producción).
Valida siempre ESTADO antes de usar el valor, y registra la GLOSA para diagnosticar.
6. Cómo usar el token en las siguientes peticiones
El token identifica tu sesión. Se usa de dos maneras según el servicio del SII:
a) Servicios de envío (subir DTE) — el token viaja en la cabecera HTTP Cookie: TOKEN=…:
using var peticion = new HttpRequestMessage(HttpMethod.Post, urlDteUpload)
{
Content = contenidoMultipart // rutSender, dvSender, rutCompany, dvCompany, archivo XML…
};
peticion.Headers.Add("Cookie", $"TOKEN={token}");
using var respuesta = await http.SendAsync(peticion);
b) Servicios de consulta (estado de envío / DTE) — el token se pasa como parámetro del método
SOAP, por ejemplo getEstUp(rutEmisor, dv, trackId, token) o getEstDte(…, token).
Vigencia: el token es temporal. Reutilízalo mientras sea válido para varias operaciones de la misma sesión y, cuando el SII responda que el token no es válido, vuelve a ejecutar el flujo semilla → firma → token para obtener uno nuevo.
7. Descarga el código completo (GitHub)
El flujo completo y funcional —cliente SOAP nativo de getSeed/getToken, la firma de la semilla y
la carga del certificado desde archivo .pfx o desde el almacén de Windows— está disponible como
proyecto de consola en C# / .NET 10, listo para abrir en Visual Studio Code:
Clónalo y pruébalo en el ambiente de certificación del SII:
git clone https://github.com/ABANCERT/sii-token-dotnet.git
cd sii-token-dotnet
dotnet run --project TokenSII -- --pfx "C:\ruta\mi.pfx" --clave miClave
Sobre ABANCERT
ABANCERT provee certificados digitales de Firma Electrónica Simple compatibles con el SII, pensados para la facturación electrónica y la firma de documentos tributarios (DTE) en Chile: emisión en línea, validez inmediata y soporte experto.
- 🌐 Sitio web: www.abancert.cl
- 🧾 Solicita tu certificado digital simple: certificado digital simple
¿Te sirvió este contenido?
¿Te quedó una duda?
WhatsApp