Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Melhorar Segurança no "Código Numérico" da Chave de Acesso da NF-e #50

Open
antoniospneto opened this issue Jan 7, 2025 · 8 comments

Comments

@antoniospneto
Copy link

antoniospneto commented Jan 7, 2025

Na composição da chave de acesso da NF-e, existe uma parte chamada "Código Numérico", que serve como um valor aleatório para dificultar o conhecimento indevido da "Chave de Acesso". Este valor é gerado pelo próprio emissor da NF-e e, atualmente, na biblioteca, é tratado no seguinte trecho de código:

def calculo_codigo_aleatorio(self, campos):
#
# O código numério é um número aleatório
#
# chave += str(random.randint(0, 99999999)).strip().rjust(8, '0')
#
# Mas, por segurança, é preferível que esse número não seja
# aleatório
#
soma = 0
for c in campos:
soma += int(c) ** 3**2
TAMANHO_CODIGO = self.CODIGO.stop - self.CODIGO.start
codigo = str(soma)
if len(codigo) > TAMANHO_CODIGO:
codigo = codigo[-TAMANHO_CODIGO:]
else:
codigo = codigo.rjust(TAMANHO_CODIGO, "0")
return codigo

Por ser um projeto de código aberto, a lógica para gerar este código pode ser facilmente descoberta, permitindo que agentes mal-intencionados explorem essa vulnerabilidade para reconstruir chaves de acesso de NF-es de empresas específicas. Com as chaves de acesso em mãos, é possível acessar detalhes das notas fiscais em serviços como o consultadanfe.com sem a necessidade de um certificado digital.

Além disso, o próprio governo disponibiliza o serviço pago "Consulta NFe" da Serpro (link), que permite consultar notas fiscais completas utilizando apenas a chave de acesso, mesmo para pessoas ou empresas que não sejam diretamente interessadas (emitente, destinatário, transportador, contador ou terceiros autorizados). Isso amplifica os riscos de exposição de dados fiscais confidenciais.

Proposta de Solução

Minha sugestão é implementar o uso de uma chave secreta configurável pelo usuário, que seria utilizada para criptografar o "Código Numérico" antes de incluí-lo na chave de acesso. Essa abordagem introduziria uma camada adicional de segurança, dificultando a obtenção indevida das chaves. A responsabilidade por gerenciar e proteger essa chave secreta seria do usuário da biblioteca.

Motivação

A principal motivação para esta mudança é o crescente número de golpes envolvendo boletos falsos, baseados em informações indevidamente coletadas de notas fiscais. Há indícios de que tais dados estão sendo obtidos por meio do uso de chaves de acesso das NF-es.

Embora esta alteração não elimine totalmente o problema, já que ataques de força bruta ainda seriam possíveis, representa um avanço significativo na proteção das empresas. A ausência de criptografia no "Código Numérico" atualmente facilita a obtenção de informações confidenciais, algo que pode ser mitigado com esta proposta.

cc @rvalyi @marcelsavegnago @mileo @renatonlima

@leorochael
Copy link

Pergunta de leigo...

No código em questão tem um comentário:

Mas, por segurança, é preferível que esse número não seja aleatório

Não entendi a razão. Porque não utilizar um número realmente aleatório?

Qual é a "segurança" que um número realmente aleatório compromete?

@antoniospneto
Copy link
Author

Pergunta de leigo...

No código em questão tem um comentário:

Mas, por segurança, é preferível que esse número não seja aleatório

Não entendi a razão. Porque não utilizar um número realmente aleatório?

Qual é a "segurança" que um número realmente aleatório compromete?

Fiquei na dúvida também,

@mileo parece que foi você que escreveu o código na época, você lembra o motivo?

@mileo
Copy link
Member

mileo commented Jan 8, 2025

Pra que fique fácil de gerar o numero novamente e consultar a nota.

Mas uma implementação aleatória que garanta isso e que garanta que seja possível consultar a nota é bem vinda.

No fluxo de emissão implementado anos atrás primeiro consultávamos a nota para ver se ela já tinha sido emitida, e pra isso precisamos da chave, caso ela já tenha sido emitida, atualizamos o status da mesma no sistema em vez de tentar novamente.

Usar um numero aleatório precisamos garantir que esta aleatoriedade vai ser controlada e chave não vai ser alterada, para permitir a consulta correta caso seja necessário.

@mileo
Copy link
Member

mileo commented Jan 8, 2025

Pergunta de leigo...

No código em questão tem um comentário:

Mas, por segurança, é preferível que esse número não seja aleatório

Não entendi a razão. Porque não utilizar um número realmente aleatório?

Qual é a "segurança" que um número realmente aleatório compromete?

Ta de volta ao Brasil?

@leorochael
Copy link

@mileo

Ta de volta ao Brasil?

não 😅 vim parar aqui por uma curiosidade de ler a mensagem no telegram...

@antoniospneto
Copy link
Author

antoniospneto commented Jan 8, 2025

Pra que fique fácil de gerar o numero novamente e consultar a nota.

Mas uma implementação aleatória que garanta isso e que garanta que seja possível consultar a nota é bem vinda.

No fluxo de emissão implementado anos atrás primeiro consultávamos a nota para ver se ela já tinha sido emitida, e pra isso precisamos da chave, caso ela já tenha sido emitida, atualizamos o status da mesma no sistema em vez de tentar novamente.

Usar um numero aleatório precisamos garantir que esta aleatoriedade vai ser controlada e chave não vai ser alterada, para permitir a consulta correta caso seja necessário.

Mas você diz caso a empresa tenha perdido a chave de acesso? por exemplo por alguma falha do sistema a nota foi transmitida, mas nenhuma informação foi salva no sistema, isso?

@antoniospneto
Copy link
Author

@mileo acho que então a ideia de incluir uma "chave secreta" na logica de montar o código númerico vai atender bem.

@mileo
Copy link
Member

mileo commented Jan 8, 2025

@mileo acho que então a ideia de incluir uma "chave secreta" na logica de montar o código númerico vai atender bem.

Sim, desde que haja previsibilidade na geração do número novamente, através por exemplo de uma semente que fique no cadastro da empresa.

E ela pode ser aleatória.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants