Getting started

O que é a solução?

Unificamos e simplificamos o uso de diversos dispositivos criptográficos em uma única plataforma de rápida integração. Cuidamos de todo o ciclo de vida do processo desde a autenticação, tokenização e geração dos resumos criptográficos.

Essa solução é a ideal para o meu negócio?

Precisa oferecer suporte a assinatura e/ou criptografia nos padrões ICP-Brasil no seu sistema e não quer perder tempo desenvolvendo e mantendo uma solução para comunicação com certificados A1/A3 e ainda se preocupando com diversos protocolos de conexão com smartcards/tokens etc? Se sim, essa é a solução ideal para você conseguir estar a frente do mercado e continuar com o foco principal do seu software.

Quais são os dispositivos compatíveis?

São compatíveis todos os certificados digitais aderentes a ICP-Brasil. O que é preciso observar é onde esse certificado está armazenado.

Os certificados comumente encontrados no mercado são os do tipo A1 e A3. Aí que está a principal diferença, os certificados do tipo A3 precisam ser emitidos e armazenados em dispositivos de segurança tais como: tokens, cartões e HSMs. Já os certificados do tipo A1 podem ser emitidos diretamente no seu computador fora de um hardware de segurança específico para tal finalidade (por isso os certificados A1 possuem um nível de classificação de segurança inferior e consequentemente só podem receber um menor tempo de expiração/vencimento)

No universo WEB acessar dispositivos de hardware via porta USB/rede (A3) ou arquivos na máquina (A1) requerem um plugin para possibilitar a comunicação do site web com um componente local instalado na máquina. A nossa plataforma possui um plugin próprio e abstrai toda a comunicação entre esses componentes, tornando indiferente para o processo de assinatura o tipo de certificado e se ele está armazenado em um arquivo, token/smartcard.

Também somos compatíveis com o mais novo padrão da ICP-Brasil, o certificado em nuvem: O certificado em nuvem pode ser um A1/A3 que fica armazenado na infraestrutura de um PSC - (Prestador de serviço de confiança credenciado ICP Brasil). Esse armazenamento em nuvem possui diversas vantagens tanto no uso quanto na segurança, com o uso do certificado em nuvem a nossa plataforma não requer o uso do plugin instalado no computador para realizar as operações criptografícas, podendo ser feitas até mesmo em um smartphone ou tablet.

Como funciona?

1º Passo

De dentro do seu sistema, redirecione o usuário para a plataforma carregando um payload de transação. Nesse payload deve conter as informações dos documentos a serem assinados e qual URL do seu sistema o usuário será redirecionado de volta ao finalizar a assinatura.

2º Passo

Receba o usuário na URL definida no primeiro passo. Junto a essa URL será retornado o payload do processo de assinatura com as informações dos documentos já assinados

Exemplo

Chamada de redirecionamento:

https://sandbox-assinatura.gestao.plus/sign/<PAYLOAD>

Como compor o payload:

O payload esperado deve ser no formato JSON

{
	"callbackUrl": "https://myfrontend-routesample?origin=usersamplexpto&state=anystate&payload=",
	"webhookUrl": "https://mybackend-routesample?origin=usersamplexpto&state=anystate",
	"security": {
		"allowAddNewDocument": false,
		"allowDocumentType": false,
    "payloadCallbackUrl": true
	},
	"files": [{
			"name": "Sample PDF",
			"src": "http://nematoides.com.br/Content/Fotos/exemplo-de-pdf.pdf"
		},
		{
			"name": "Sample PDF 2",
			"src": "data:application/pdf;base64,JVBERi0xLjUKJbXtrvsKMyAwIG9iago8PCAvTGVuZ3RoIDQgMCBSCiAgIC9GaWx0ZXIgL0ZsYXRlRGVjb2RlCj4+CnN0cmVhbQp4nE2NuwoCQQxF+/mK+wMbk5lkHl+wIFislmIhPhYEi10Lf9/MVgZCAufmZAkMppJ6+ZLUuFWsM3ZXxvzpFNaMYjEriqpCtbZSBOsDzw0zjqPHZYtTrEmz4eto7/0K54t7GfegOGCBbBdDH3+y2zsMsVERc9SoRkXORqKGJupS6/9OmMIUfgypJL4KZW5kc3RyZWFtCmVuZG9iago0IDAgb2JqCiAgIDEzOAplbmRvYmoKMiAwIG9iago8PAogICAvRXh0R1N0YXRlIDw8CiAgICAgIC9hMCA8PCAvQ0EgMC42MTE5ODcgL2NhIDAuNjExOTg3ID4+CiAgICAgIC9hMSA8PCAvQ0EgMSAvY2EgMSA+PgogICA+Pgo+PgplbmRvYmoKNSAwIG9iago8PCAvVHlwZSAvUGFnZQogICAvUGFyZW50IDEgMCBSCiAgIC9NZWRpYUJveCBbIDAgMCA1OTUuMjc1NTc0IDg0MS44ODk3NzEgXQogICAvQ29udGVudHMgMyAwIFIKICAgL0dyb3VwIDw8CiAgICAgIC9UeXBlIC9Hcm91cAogICAgICAvUyAvVHJhbnNwYXJlbmN5CiAgICAgIC9DUyAvRGV2aWNlUkdCCiAgID4+CiAgIC9SZXNvdXJjZXMgMiAwIFIKPj4KZW5kb2JqCjEgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzCiAgIC9LaWRzIFsgNSAwIFIgXQogICAvQ291bnQgMQo+PgplbmRvYmoKNiAwIG9iago8PCAvQ3JlYXRvciAoY2Fpcm8gMS4xMS4yIChodHRwOi8vY2Fpcm9ncmFwaGljcy5vcmcpKQogICAvUHJvZHVjZXIgKGNhaXJvIDEuMTEuMiAoaHR0cDovL2NhaXJvZ3JhcGhpY3Mub3JnKSkKPj4KZW5kb2JqCjcgMCBvYmoKPDwgL1R5cGUgL0NhdGFsb2cKICAgL1BhZ2VzIDEgMCBSCj4+CmVuZG9iagp4cmVmCjAgOAowMDAwMDAwMDAwIDY1NTM1IGYgCjAwMDAwMDA1ODAgMDAwMDAgbiAKMDAwMDAwMDI1MiAwMDAwMCBuIAowMDAwMDAwMDE1IDAwMDAwIG4gCjAwMDAwMDAyMzAgMDAwMDAgbiAKMDAwMDAwMDM2NiAwMDAwMCBuIAowMDAwMDAwNjQ1IDAwMDAwIG4gCjAwMDAwMDA3NzIgMDAwMDAgbiAKdHJhaWxlcgo8PCAvU2l6ZSA4CiAgIC9Sb290IDcgMCBSCiAgIC9JbmZvIDYgMCBSCj4+CnN0YXJ0eHJlZgo4MjQKJSVFT0YK"
		}
	]
}

Pode ser necessário a inclusão do endpoint https://sandbox-assinatura.gestao.plus na whitelist de CORS de onde o PDF está armazenado. (GET/HEAD) Veja como habilitar esse recurso em um bucket AWS/S3 https://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html#how-do-i-enable-cors

Como envelopar o payload e computar URL com token HMAC:

O payload deve ser assinado para garantir a origem/integridade da URL de redirecionamento

<?php

$plusGApp = "https://sandbox-assinatura.gestao.plus/sign";
$sharedKey = "MY_SECRET";

$payloadJson = '{"callbackUrl":"https://myfrontend-routesample?origin=usersamplexpto&state=anystate&payload=","webhookUrl":"https://mybackend-routesample?origin=usersamplexpto&state=anystate","security":{"allowAddNewDocument":false,"allowDocumentType":false,"payloadCallbackUrl":true},"files":[{"name":"Sample PDF","src":"http://nematoides.com.br/Content/Fotos/exemplo-de-pdf.pdf"},{"name":"Sample PDF 2","src":"data:application/pdf;base64,JVBERi0xLjUKJbXtrvsKMyAwIG9iago8PCAvTGVuZ3RoIDQgMCBSCiAgIC9GaWx0ZXIgL0ZsYXRlRGVjb2RlCj4+CnN0cmVhbQp4nE2NuwoCQQxF+/mK+wMbk5lkHl+wIFislmIhPhYEi10Lf9/MVgZCAufmZAkMppJ6+ZLUuFWsM3ZXxvzpFNaMYjEriqpCtbZSBOsDzw0zjqPHZYtTrEmz4eto7/0K54t7GfegOGCBbBdDH3+y2zsMsVERc9SoRkXORqKGJupS6/9OmMIUfgypJL4KZW5kc3RyZWFtCmVuZG9iago0IDAgb2JqCiAgIDEzOAplbmRvYmoKMiAwIG9iago8PAogICAvRXh0R1N0YXRlIDw8CiAgICAgIC9hMCA8PCAvQ0EgMC42MTE5ODcgL2NhIDAuNjExOTg3ID4+CiAgICAgIC9hMSA8PCAvQ0EgMSAvY2EgMSA+PgogICA+Pgo+PgplbmRvYmoKNSAwIG9iago8PCAvVHlwZSAvUGFnZQogICAvUGFyZW50IDEgMCBSCiAgIC9NZWRpYUJveCBbIDAgMCA1OTUuMjc1NTc0IDg0MS44ODk3NzEgXQogICAvQ29udGVudHMgMyAwIFIKICAgL0dyb3VwIDw8CiAgICAgIC9UeXBlIC9Hcm91cAogICAgICAvUyAvVHJhbnNwYXJlbmN5CiAgICAgIC9DUyAvRGV2aWNlUkdCCiAgID4+CiAgIC9SZXNvdXJjZXMgMiAwIFIKPj4KZW5kb2JqCjEgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzCiAgIC9LaWRzIFsgNSAwIFIgXQogICAvQ291bnQgMQo+PgplbmRvYmoKNiAwIG9iago8PCAvQ3JlYXRvciAoY2Fpcm8gMS4xMS4yIChodHRwOi8vY2Fpcm9ncmFwaGljcy5vcmcpKQogICAvUHJvZHVjZXIgKGNhaXJvIDEuMTEuMiAoaHR0cDovL2NhaXJvZ3JhcGhpY3Mub3JnKSkKPj4KZW5kb2JqCjcgMCBvYmoKPDwgL1R5cGUgL0NhdGFsb2cKICAgL1BhZ2VzIDEgMCBSCj4+CmVuZG9iagp4cmVmCjAgOAowMDAwMDAwMDAwIDY1NTM1IGYgCjAwMDAwMDA1ODAgMDAwMDAgbiAKMDAwMDAwMDI1MiAwMDAwMCBuIAowMDAwMDAwMDE1IDAwMDAwIG4gCjAwMDAwMDAyMzAgMDAwMDAgbiAKMDAwMDAwMDM2NiAwMDAwMCBuIAowMDAwMDAwNjQ1IDAwMDAwIG4gCjAwMDAwMDA3NzIgMDAwMDAgbiAKdHJhaWxlcgo8PCAvU2l6ZSA4CiAgIC9Sb290IDcgMCBSCiAgIC9JbmZvIDYgMCBSCj4+CnN0YXJ0eHJlZgo4MjQKJSVFT0YK"}]}';

//Payload
$payloadEncoded = base64_encode($payloadJson);

//Compute HMAC
$nonce = time() . rand(0,9999);
$token = $nonce . "-" . md5($nonce . $sharedKey . md5($payloadEncoded));

//URL
$url = $plusGApp . '/' . $token . '/' . urlencode($payloadEncoded);

echo $url;

Como esperar o callback de retorno do frontend (web/deep linking app):

Ao criar o payload de envio pode ser criado uma URL prévia da URL de retorno da sua aplicação, contendo as informações de estado da aplicação (exemplo: tela de retorno, usuário logado etc)

https://myfrontend-routesample?origin=usersamplexpto&state=anystate

Caso no payload seja solicitado também os ids e URLS dos documentos assinados (através da ativação da flag em: security -> payloadCallbackUrl ) a url de retorno deve estar preparada para o payload ser concatenado no final, exemplo:

https://myfrontend-routesample?origin=usersamplexpto&state=anystate&payload=

Como esperar o webhook de retorno:

Será enviada uma requisição REST do tipo POST com o JSON de retorno do Webhook, o endpoint enviado de retorno de webhook da sua aplicação deve esperar o formato:

{
  "message": "Signed OK",
  "documents": [{
    "id": 0,
    "downloadLink": "https://sandbox-assinatura.gestao.plus/storage/0-bcbb5b72af85a68709f12c9bdfbd1efd759522d3.pdf"
  }, {
    "id": 1,
    "downloadLink": "https://sandbox-assinatura.gestao.plus/storage/1-d5e5b6f4b3b7ea13920286d400b4fa1d34512f2b.pdf"
  }]
}

Exemplo no cenário médico (CFM/CFF)

Especificando o tipo de arquivo

É possível através do payload indiciar o tipo de documento (por arquivo), essa opção esconde o combobox na hora da assinatura.

Ex:

{
	...
	"files": [{
		"name": "Sample Base64",
		"id": "token-1",
		"src": "data:application\/pdf;base64,JVBERi0xLjUKJbXtrvsKMyAwIG9iago8PCAvTGVuZ3RoIDQgMCBSCiAgIC9GaWx0ZXIgL0ZsYXRlRGVjb2RlCj4+CnN0cmVhbQp4nE2NuwoCQQxF+\/mK+wMbk5lkHl+wIFislmIhPhYEi10Lf9\/MVgZCAufmZAkMppJ6+ZLUuFWsM3ZXxvzpFNaMYjEriqpCtbZSBOsDzw0zjqPHZYtTrEmz4eto7\/0K54t7GfegOGCBbBdDH3+y2zsMsVERc9SoRkXORqKGJupS6\/9OmMIUfgypJL4KZW5kc3RyZWFtCmVuZG9iago0IDAgb2JqCiAgIDEzOAplbmRvYmoKMiAwIG9iago8PAogICAvRXh0R1N0YXRlIDw8CiAgICAgIC9hMCA8PCAvQ0EgMC42MTE5ODcgL2NhIDAuNjExOTg3ID4+CiAgICAgIC9hMSA8PCAvQ0EgMSAvY2EgMSA+PgogICA+Pgo+PgplbmRvYmoKNSAwIG9iago8PCAvVHlwZSAvUGFnZQogICAvUGFyZW50IDEgMCBSCiAgIC9NZWRpYUJveCBbIDAgMCA1OTUuMjc1NTc0IDg0MS44ODk3NzEgXQogICAvQ29udGVudHMgMyAwIFIKICAgL0dyb3VwIDw8CiAgICAgIC9UeXBlIC9Hcm91cAogICAgICAvUyAvVHJhbnNwYXJlbmN5CiAgICAgIC9DUyAvRGV2aWNlUkdCCiAgID4+CiAgIC9SZXNvdXJjZXMgMiAwIFIKPj4KZW5kb2JqCjEgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzCiAgIC9LaWRzIFsgNSAwIFIgXQogICAvQ291bnQgMQo+PgplbmRvYmoKNiAwIG9iago8PCAvQ3JlYXRvciAoY2Fpcm8gMS4xMS4yIChodHRwOi8vY2Fpcm9ncmFwaGljcy5vcmcpKQogICAvUHJvZHVjZXIgKGNhaXJvIDEuMTEuMiAoaHR0cDovL2NhaXJvZ3JhcGhpY3Mub3JnKSkKPj4KZW5kb2JqCjcgMCBvYmoKPDwgL1R5cGUgL0NhdGFsb2cKICAgL1BhZ2VzIDEgMCBSCj4+CmVuZG9iagp4cmVmCjAgOAowMDAwMDAwMDAwIDY1NTM1IGYgCjAwMDAwMDA1ODAgMDAwMDAgbiAKMDAwMDAwMDI1MiAwMDAwMCBuIAowMDAwMDAwMDE1IDAwMDAwIG4gCjAwMDAwMDAyMzAgMDAwMDAgbiAKMDAwMDAwMDM2NiAwMDAwMCBuIAowMDAwMDAwNjQ1IDAwMDAwIG4gCjAwMDAwMDA3NzIgMDAwMDAgbiAKdHJhaWxlcgo8PCAvU2l6ZSA4CiAgIC9Sb290IDcgMCBSCiAgIC9JbmZvIDYgMCBSCj4+CnN0YXJ0eHJlZgo4MjQKJSVFT0YK",
		"signatureSetting": {
			"type": "CFMBR-2.16.76.1.12.1.11"
		}
	}, {
		"name": "Name Xpty",
		"id": "token-2",
		"src": "https:\/\/cdn.rawgit.com\/mozilla\/pdf.js\/c6e8ca86\/test\/pdfs\/calrgb.pdf",
		"signatureSetting": {
			"type": "CFMBR-2.16.76.1.12.1.6"
		}
	}]
}

Especificando os campos adicionais

O portal de validação de documentos digitais do ITI (Instituto Nacional de Tecnologia da Informação) em parceria com CFM (Conselho Federal de Medicina.) e CFF (Conselho Federal de Farmácia) espera alguns metadados do profissional como número do CRM/CFF e UF durante o processo de assinatura. A lista completa pode ser conferida no site https://assinaturadigital.iti.gov.br/duvidas/#1587761771301-8f0416f4-c42c Esses campos também devem ser adicionados no payload para serem incluídos na hora da assinatura.

Ex:

{
	...
	"extraKeys": [{
		"name": "2.16.76.1.4.2.2.1",
		"value": "1234567"
	}, {
		"name": "2.16.76.1.4.2.2.2",
		"value": "GO"
	}],
	... 
}

Exemplo completo de payload no cenário médico:

{
	"callbackUrl": "https:\/\/api-sandbox-assinatura.gestao.plus\/sample.php?signed=true&payload=",
	"webhookUrl": "https:\/\/gestao.plus\/?origin=usersamplexpto&state=anystate",
	"extraKeys": [{
		"name": "2.16.76.1.4.2.2.1",
		"value": "1234567"
	}, {
		"name": "2.16.76.1.4.2.2.2",
		"value": "GO"
	}],
	"ui": {
		"username": "65415708090"
	},
	"security": {
		"allowAddNewDocument": false,
		"allowDocumentType": false,
		"payloadCallUrl": true
	},
	"files": [{
		"name": "Sample Base64",
		"id": "token-1",
		"src": "data:application\/pdf;base64,JVBERi0xLjUKJbXtrvsKMyAwIG9iago8PCAvTGVuZ3RoIDQgMCBSCiAgIC9GaWx0ZXIgL0ZsYXRlRGVjb2RlCj4+CnN0cmVhbQp4nE2NuwoCQQxF+\/mK+wMbk5lkHl+wIFislmIhPhYEi10Lf9\/MVgZCAufmZAkMppJ6+ZLUuFWsM3ZXxvzpFNaMYjEriqpCtbZSBOsDzw0zjqPHZYtTrEmz4eto7\/0K54t7GfegOGCBbBdDH3+y2zsMsVERc9SoRkXORqKGJupS6\/9OmMIUfgypJL4KZW5kc3RyZWFtCmVuZG9iago0IDAgb2JqCiAgIDEzOAplbmRvYmoKMiAwIG9iago8PAogICAvRXh0R1N0YXRlIDw8CiAgICAgIC9hMCA8PCAvQ0EgMC42MTE5ODcgL2NhIDAuNjExOTg3ID4+CiAgICAgIC9hMSA8PCAvQ0EgMSAvY2EgMSA+PgogICA+Pgo+PgplbmRvYmoKNSAwIG9iago8PCAvVHlwZSAvUGFnZQogICAvUGFyZW50IDEgMCBSCiAgIC9NZWRpYUJveCBbIDAgMCA1OTUuMjc1NTc0IDg0MS44ODk3NzEgXQogICAvQ29udGVudHMgMyAwIFIKICAgL0dyb3VwIDw8CiAgICAgIC9UeXBlIC9Hcm91cAogICAgICAvUyAvVHJhbnNwYXJlbmN5CiAgICAgIC9DUyAvRGV2aWNlUkdCCiAgID4+CiAgIC9SZXNvdXJjZXMgMiAwIFIKPj4KZW5kb2JqCjEgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzCiAgIC9LaWRzIFsgNSAwIFIgXQogICAvQ291bnQgMQo+PgplbmRvYmoKNiAwIG9iago8PCAvQ3JlYXRvciAoY2Fpcm8gMS4xMS4yIChodHRwOi8vY2Fpcm9ncmFwaGljcy5vcmcpKQogICAvUHJvZHVjZXIgKGNhaXJvIDEuMTEuMiAoaHR0cDovL2NhaXJvZ3JhcGhpY3Mub3JnKSkKPj4KZW5kb2JqCjcgMCBvYmoKPDwgL1R5cGUgL0NhdGFsb2cKICAgL1BhZ2VzIDEgMCBSCj4+CmVuZG9iagp4cmVmCjAgOAowMDAwMDAwMDAwIDY1NTM1IGYgCjAwMDAwMDA1ODAgMDAwMDAgbiAKMDAwMDAwMDI1MiAwMDAwMCBuIAowMDAwMDAwMDE1IDAwMDAwIG4gCjAwMDAwMDAyMzAgMDAwMDAgbiAKMDAwMDAwMDM2NiAwMDAwMCBuIAowMDAwMDAwNjQ1IDAwMDAwIG4gCjAwMDAwMDA3NzIgMDAwMDAgbiAKdHJhaWxlcgo8PCAvU2l6ZSA4CiAgIC9Sb290IDcgMCBSCiAgIC9JbmZvIDYgMCBSCj4+CnN0YXJ0eHJlZgo4MjQKJSVFT0YK",
		"signatureSetting": {
			"type": "CFMBR-2.16.76.1.12.1.11"
		}
	}, {
		"name": "Name Xpty",
		"id": "token-2",
		"src": "https:\/\/cdn.rawgit.com\/mozilla\/pdf.js\/c6e8ca86\/test\/pdfs\/calrgb.pdf",
		"signatureSetting": {
			"type": "CFMBR-2.16.76.1.12.1.6"
		}
	}]
}

Last updated