> For the complete documentation index, see [llms.txt](https://portal-integracao.intelbras.com.br/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://portal-integracao.intelbras.com.br/linha-de-faciais/configuracao-de-credencial-qrcode/funcionamento.md).

# Funcionamento

## QR Code

Atualmente é suportada a opção para a utilização do QR Code em modo criptografado e não criptografado.

### Modo Criptografado

Este modo não expõe a credencial do usuário e utiliza um timestamp para validar o QR code, inibindo cópias e utilização de QR codes antigos. Este modo é habilitado por padrão, deve ser utilizado na geração do QR Code por meio do seguinte algoritmo:

#### Exemplos

{% tabs %}
{% tab title="Python" %}

```python
  import base64
  import time
  import qrcode
  from Crypto.Cipher import AES
 
  class IntelbrasQREnc(object):
 
      def __init__(self, key): 
          self.key = key.encode('utf-8')
          self.iv = int(0).to_bytes(16, byteorder='big')
 
      def encrypt(self, cardNrHexStr):
          # convert cardNr string to bytes (4 bytes)
          cardNrHex = int(cardNrHexStr,16).to_bytes(4, byteorder='big')
          # get the epoch unix time (4 bytes)
          timeEpochHex = (int(time.time())).to_bytes(4, byteorder='big')
          print("Used epochTime: ",  int.from_bytes(timeEpochHex, byteorder='big', signed=True))
          # concatenate timeEpoch and CardNr
          toEnc = timeEpochHex + cardNrHex
          # create the cipher object
          cipher = AES.new(self.key, AES.MODE_OFB, self.iv)   
          # Encrypt the data
          enc = cipher.encrypt(toEnc)
          # encode the encrypted data with base64
          base64enc =  base64.b64encode(enc)
          # Concatenate prefix string
          return str(base64enc, 'utf-8')
 
  # key must be 32 chars string with printable chars (utf-8)
  key = '0123456789ABCDEF0123456789ABCDEF'
  # Card number must be in string in Hex, maximum value "FFFFFFFF", 32bits
  cardNr = "4401964D"
 
  print("Encrypting:...")
  print("CardNr to enc: ", cardNr)
 
  # Create the IntelbrasQREnc object
  QREnc = IntelbrasQREnc(key)
 
  # Create the encrypted message from card
  qrcodeStr = QREnc.encrypt(cardNr)
  print("Encoded string: ", qrcodeStr)
  print("\n")
 
  # Generate qrcode image from crypted data
  img = qrcode.make(qrcodeStr)
  type(img)  # qrcode.image.pil.PilImage
  img.save("qrcode.png")
```

{% endtab %}

{% tab title="Node" %}

```javascript
var aesjs = require('aes-js');
var QRCode = require('qrcode')
 
function encrypt(_key, _cardNr)
{
    var key = aesjs.utils.utf8.toBytes(_key);
    var iv = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ];
    var cardNr = _cardNr
    
    var epochTime = aesjs.utils.hex.toBytes((Math.floor(new Date() / 1000).toString(16)));
    var textBytes = aesjs.utils.hex.toBytes(cardNr);
 
    var dataToEnc = new Uint8Array(epochTime.length + textBytes.length)
    dataToEnc.set(epochTime);
    dataToEnc.set(textBytes, epochTime.length);
 
    //console.log('data to encrypt: ', dataToEnc)
 
    var aesOfb = new aesjs.ModeOfOperation.ofb(key, iv);
    var encryptedBytes = aesOfb.encrypt(dataToEnc);
    var b64 = Buffer.from(encryptedBytes).toString('base64');
    return b64;
}
 
encdata = encrypt('0123456789ABCDEF0123456789ABCDEF', '4401964D');
console.log('Encrypted data: ', encdata);
QRCode.toFile('qrcode.png',encdata);
```

{% endtab %}
{% endtabs %}

#### Passos para utilização

1º - Cadastrar Chave de Segurança no Dispositivo (deve conter 32 caracteres ou 265 bits)

2º - Cadastrar número cartão do usuário no dispositivo (hexadecimal)

3º - Gerar QR code com hash do número do cartão e a senha de segurança (utilizando algoritmo em python).

Fluxograma de exemplo:

![Fluxograma Exemplo Cadastro QR Code Cifrado](https://i.imgur.com/epyeOjS.png)

**Usuário Visitante**: O acesso é limitado pela validade da credencial do usuário, pela quantidade de acesso permitido. O Cadastro do usuário visitante é feito pela utilização do paramêtro `UserType` durante o cadastro do usuário, sendo **UserType=2** o usuário do tipo visitante.

**Usuário Comum**: O acesso é limitado pela validade da credencial do usuário, zona de tempo, timeout de 10 minutos após a geração do QR code. O Cadastro do usuário normal é feito pela utilização do paramêtro UserType durante o cadastro do usuário, sendo **UserType=0** o usuário do tipo normal.

{% hint style="warning" %}
Obs: Neste modo é necessário que o relógio do dispositivo esteja correto.
{% endhint %}

### Cadastrar Chave de Segurança

Por meio desta opção é realizado o cadastro da chave de segurança ao dispositivo que realizará a leitura do QRcode com criptografia.

{% hint style="warning" %}
Obs: Esta chave deve ser gerada e única para cada cenário e não deve ser compartilhada
{% endhint %}

#### Requisição - GET

`http://192.168.1.201/cgi-bin/configManager.cgi?action=setConfig&QRCodeDecode.key=6PNKDVQEU6YOULVYDDJW2SISEBNVUOPU`

| param          | type      | description                                        |
| -------------- | --------- | -------------------------------------------------- |
| `setConfig` \* | String    | Comando para cadastrar configuração                |
| `key`          | Timestamp | Chave do QRcode, deve ser no máximo 32 caracteres. |

#### Exemplo de Retorno - *text/plain*

```sh
OK
```

### Obter Chave de Segurança

Obs: Esta chave deve ser gerada e única para cada cenário e não deve ser compartilhada

#### Requisição - GET

`http://192.168.1.201/cgi-bin/configManager.cgi?action=getConfig&name=QRCodeDecode`

| param          | type      | description                     |
| -------------- | --------- | ------------------------------- |
| `getConfig` \* | String    | Comando para obter configuração |
| `QRCodeDecode` | Timestamp | QRCodeDecode                    |

#### Exemplo de Retorno - *text/plain*

```sh
table.QRCodeDecode.cipher=0
table.QRCodeDecode.key=6PNKDVQEU6YOULVYDDJW2SISEBNVUOPu
```

#### Exemplos

{% tabs %}
{% tab title="Python" %}

```python
import requests
 
device_ip = '10.1.35.144'
username = 'admin'
password = 'acesso1234'
 
url = "http://{}/cgi-bin/configManager.cgi?action=getConfig&name=QRCodeDecode".format(
                          str(device_ip),
                      )
 
digest_auth = requests.auth.HTTPDigestAuth(username, password)
rval = requests.get(url, auth=digest_auth, stream=True, timeout=20, verify=False)
 
print(rval.text)
```

{% endtab %}
{% endtabs %}

### Alterar Tipo de QR Code (Sem Segurança)

Ao Habilitar o QRcode sem segurança, qualquer cartão cadastrado no dispositivo, é passível de ser lido via QRcode e será realizado a abertura da porta de acordo com as regras do cadastro. Neste modo outros caracteres fora cartões tambem serão lidos pelo dispositivo e retornados no campo Cardno nos eventos.

No modo sem criptografia, outros qr codes que não estejam no formato de cartão serão lidos e repassados ao campo CardNo.

#### Requisição - GET

`http://192.168.1.201/cgi-bin/configManager.cgi?action=setConfig&_EnableUnsecure_.Enable=true`

| param          | type      | description                               |
| -------------- | --------- | ----------------------------------------- |
| `setConfig` \* | String    | Comando para realizar configuração        |
| `Enable`       | Timestamp | Habilita/Desabilita a segurança do QRcode |

#### Exemplo de Retorno - *text/plain*

```sh
OK
```

#### Exemplos

{% tabs %}
{% tab title="Python" %}

```python
import requests
 
device_ip = '10.1.35.144'
username = 'admin'
password = 'acesso1234'
 
url = "http://{}/cgi-bin/configManager.cgi?action=setConfig&_EnableUnsecure_.Enable=true".format(
                          str(device_ip),
                      )
 
digest_auth = requests.auth.HTTPDigestAuth(username, password)
rval = requests.get(url, auth=digest_auth, stream=True, timeout=20, verify=False)
 
print(rval.text)
```

{% endtab %}
{% endtabs %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://portal-integracao.intelbras.com.br/linha-de-faciais/configuracao-de-credencial-qrcode/funcionamento.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
