Criptografia em AdvPL – Parte 15

Introdução

No post anterior (Criptografia em AdvPL – Parte 14) vimos mais funções de assinatura digital, módulo e expoente das chaves criptográficas, e a diferença entre uma PUBLIC KEY e uma RSA PUBLIC KEY. Agora, vamos ver mais uma forma de assinar digitalmente no AdvPL 😀 Para ver o índice de tudo o que já foi publicado nessa série de posts, acesse o link Criptografia e Segurança.

É possível assinar outros conteúdos no AdvPL ?

Sim, o AdvPL ainda oferece a função SMimeSign(), criada para assinar conteúdos em formato MIME (Multipurpose Internet Mail Extensions) – usados para e-mails e afins — através de um certificado digital junto com uma chave criptográfica privada.

Função AdvPL SMimeSign()

Documentada no TDN no link https://tdn.totvs.com/display/tec/SMIMESign, ela permite assinar de várias formas um conteúdo em formato MIME — como um e-mail por exemplo — ou mesmo um texto plano, ou outro conteúdo qualquer. A primeira diferença importante desta função para as demais é que o certificado e a chave privada devem ser informados com o caminho completo (unidade de disco + path), sendo assim o certificado e a chave usados não precisam estar dentro do RootPath do ambiente.Vamos ver como utilizá-la na série de exemplos a seguir.

Requisitos

Para os próximos testes, vamos utilizar o mesmo certificado e chave privada de exemplo usado para o HTTPS dos posts anteriores  (note-juliow-ssd.cer e note-juliow-ssd.key).

Equivalência com a OpenSSL

A ferramenta de linha de comando OpenSSL possui o comando “smime”, que permite não apenas assinar um conteúdo, mas criptografá-lo, descriptografá-lo e verificar a validade de uma assinatura, e por default o formato de saída (output) da instrução de assinatura é SMIME. A função SMimeSign() engloba apenas a opção de assinatura, e o formato de retorno é PKCS7 PEM — codificado em Base64.

Primeira assinatura

Eu tenho uma mensagem em texto plano, apenas a string “Meu teste de assinatura MIME”, e quero gerar uma assinatura desse texto usando meu certificado de testes e a chave privada desse certificado. Para fazer isso em um fonte AdvPL, eu posso proceder por exemplo da seguinte forma:

User Function MSign1()
local cSignCert := "C:\Protheus12LG\EnvLight\certificates\note-juliow-ssd.cer"
local cPrivKey := "C:\Protheus12LG\EnvLight\certificates\note-juliow-ssd.key"
local cData := 'Meu teste de assinatura MIME'
local cError := ""
local cSigned := ""

cSigned := SMIMESign( cSignCert, cPrivKey, cData, '', @cError, '' )

If empty(cSigned)
  conout("SMIMESign ERROR : "+cError)
Else
  conout("SMIMESign OK ")
  memowrit('\certificates\message_protheus.p7s',cSigned)
Endif
Return

A chave privada usada não está protegida por senha, e a assinatura desse conteúdo será gerada no formato PKCS7 PEM no arquivo “message_protheus.p7s”. Eu posso abrir esse arquivo em um editor de textos simples para visualização, e nele eu devo ver algo assim:

-----BEGIN PKCS7-----
MIIJ2AYJKoZIhvcNAQcCoIIJyTCCCcUCAQExDzANBglghkgBZQMEAgEFADALBgkq
hkiG9w0BBwGgggYSMIIGDjCCA/agAwIBAgIUXql2ONvAPF7P9ovgz3y4XK2HWdkw
(...)

Se eu estivesse gerando essa assinatura usando a ferramenta OpenSSL, eu precisaria apenas criar um arquivo de texto simples — por exemplo mesagem.txt — contendo o texto “Meu teste de assinatura MIME”, e executar o comando abaixo:

openssl smime -sign -in message.txt  -out message_openssl.p7s -signer note-juliow-ssd.cer -inkey note-juliow-ssd.key -outform pem

O certificado digital usado para a assinatura foi informado através do parâmetro “-signer”, a chave privada do certificado informada no parâmetro “-inkey”, e mudamos o formato de saída para PEM usando o parâmetro “-outform”. Simples assim.

E o que têm “dentro” dessa assinatura ?!

Vamos pedir para a OpenSSL mostrar o que tem nessa assinatura, usando o comando abaixo:

openssl pkcs7 -inform PEM -in message_protheus.p7s -print -out message_protheus_info.txt -noout

Com esta instrução usamos o comando pkcs7 da openssl para gerar um arquivo texto (message_protheus_info.txt) com tudo o que têm dentro dessa assinatura .. são quase 13KB de informações em formato “legível”, entre elas o certificado usado para a assinatura, a chave pública do certificado, a assinatura em si, e um digest RSA criptográfico. Um ponto interessante a ser  visto neste momento é que a informação gerada não contém internamente na estrutura o texto que foi assinado, ela representa a assinatura sobre o texto informado.

Opções adicionais e seus comportamentos

A OpenSSL permite informar opções adicionais na linha de comando, normalmente cada opção é uma palavra reservada precedida por um “-” (sinal de “menos”). A função SMimeSign() também permite algumas opções adicionais, colocadas em uma string AdvPL informada para a função no mesmo formato — e quando usadas mais de uma opção simultaneamente, elas devem estar separadas entre si um espaço em branco. Veja abaixo as opções implementadas no AdvPL para a função SMimeSign():

Opção “-nodetach”

Também chamada de “assinatura opaca”, o uso dessa opção — tanto na OpenSSL quando na SMimeSign() — gera uma assinatura colocando o conteúdo da mensagem dentro da assinatura gerada. Com isso, a assinatura em si também contém o conteúdo original — sem criptografia alguma, apenas “embutido” nela.

Opção “-nocerts”

Caso eu não queira que o certificado usado para a assinatura seja gravado junto da assinatura, basta especificar a opção acima. Porém, se o destinatário da mensagem quiser verificar a assinatura, ele deve ter o certificado usado para a assinatura localmente.

Opção “-noattr”

Por default a assinatura inclui algumas informações adicionais, como por exemplo a data da assinatura e uma lista de algoritmos simétricos suportados. Usando a opção “-noattr”, estes atributos não são inseridos.

Opção “-text”

Quando usamos a opção “-nodetach”, e a mensagem assinada é incorporada dentro da assinatura, usar a opção “-text” acrescenta no inicio da mensagem assinada um header informando “Content-Type: text/plain” + CRLF + CRLF

Opção “-binary”

O uso desta opção não realiza a conversão automática das quebras de linha do conteúdo a ser assinado para CRLF. Quando queremos assinar um conteúdo que não está em formato MIME, ou que não deve ser aplicada nenhuma conversão, usamos esta opção.

Outras opções

Aparentemente as demais opções documentadas não tem efeito sobre a assinatura, como por exemplo “-noverify”, “-nochain”“-nosigs”.

Verificando uma assinatura com OpenSSL

Quando a assinatura contempla a mensagem (opção “-nodetach”), podemos verificar a assinatura da mensagem apenas usando o comando abaixo:

openssl smime -verify -inform PEM -in message_protheus.p7s -noverify

A opção “-noverify” indica que não deve ser verificado quem emitiu o certificado que assinou a mensagem, mas apenas a assinatura em si.

Quando queremos verificar uma assinatura de um determinado conteúdo que não está dentro da assinatura — default — precisamos informar a assinatura e o conteúdo a ser verificado:

openssl smime -verify -inform PEM -in message_protheus.p7s -content message.txt -noverify

Conclusão

Acredito que este post chegou na “metade” das funcionalidades criptográficas que podem ser utilizadas em AdvPL, e já temos uma boa “base” de como isso funciona. Agora, a outra metade — que está no forno — vai englobar todas as funções criptográficas que utilizam HSM (Hardware Security Module)  😀

Espero que estas informações lhes sejam úteis e proveitosas, e lhes desejo como sempre TERABYTES DE SUCESSO !!!!

Referências

 

 

 

Um comentário sobre “Criptografia em AdvPL – Parte 15

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Google

Você está comentando utilizando sua conta Google. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s