HOTP & TOTP Migration - O que o "QR-Code para migração" carrega de informação?
Relato
Precisando migrar de dispositivo o gerador de token TOTP (ou HOTP), notei que vários aplicativos autenticadores 2FA permitem transferir as configurações do algoritmo de hash, quantidade de dígitos gerados e chave secreta por meio de QR-Code. Com tal tecnologia para transferência de dados evita-se erros caso fosse necessário copiar manualmente tais detalhes. A longa chave secreta (cerca de 20 bytes), apesar de ser codificada em BASE32 ao invés de BASE64 ou sequência hexadecimal, torna-se ainda uma string relativamente mais longa.
!QR-CODE image supressed!
Aprendizado
Do QR-Code gerado pelo aplicativo para fins de migração é possivel obter a raw string usando algum leitor offline para tais QR-Codes.
[!CAUTION]
OFFLINE, pois que os segredos contidos no QR-Code jamais devem ser revelados com outras aplicações online, loggers etc. ou mesmo mantidos visíveis após a tranferência do conteúdo para o dispositivo de destino. Nos próximos parágrafos, entende-se as razões.
otpauth-migration://offline?data=CkoKD/EwZ5q6g80oq98RRQnD2hIgX0ZpY3RpY2lvdXNfTmFtZTp1c2VyQGRvbWFpbi50bGQaD0lzc3Vlcl9Db21wYW55ZSABKAEwAhABGAEgAA=='
cujo conteúdo em data
, codificado em BASE64, pode ser decodificado usando algumas aplicações na linha de comando do terminal Linux:
$ data='CkoKD/EwZ5q6g80oq98RRQnD2hIgX0ZpY3RpY2lvdXNfTmFtZTp1c2VyQGRvbWFpbi50bGQaD0lzc3Vlcl9Db21wYW55ZSABKAEwAhABGAEgAA=='
$ echo -ne "${data}" | base64 -d | hexdump -Cv
que resulta
00000000 0a 4a 0a 0f f1 30 67 9a ba 83 cd 28 ab df 11 45 |.J...0g....(...E|
00000010 09 c3 da 12 20 5f 46 69 63 74 69 63 69 6f 75 73 |.... _Ficticious|
00000020 5f 4e 61 6d 65 3a 75 73 65 72 40 64 6f 6d 61 69 |_Name:user@domai|
00000030 6e 2e 74 6c 64 1a 0f 49 73 73 75 65 72 5f 43 6f |n.tld..Issuer_Co|
00000040 6d 70 61 6e 79 65 20 01 28 01 30 02 10 01 18 01 |mpanye .(.0.....|
00000050 20 00 | .|
00000052
O conteúdo é uma stream binária que traz algumas informações em texto e parte em sequências hexadecimais. A rigor, o conteúdo está em formato Protobuf contendo alguns parâmetros aqui interpretados "manualmente" usando algumas receitas [1] [2] [3] disponíveis na internet:
0a 4a
Secret:
0a 0f
f1 30 67 9a ba 83 cd 28 ab df 11 45 09 c3 da
Name:
12 20
5f 46 69 63 74 69 63 69 6f 75 73 5f 4e 61 6d 65 3a 75 73 65 72 40 64 6f 6d 61 69 6e 2e 74 6c 64
Issuer:
1a 0f
49 73 73 75 65 72 5f 43 6f 6d 70 61 6e 79 65
Algorithm:
20 01
Digits:
28 01
Type:
30 02
Version:
10 01
Batch size:
18 01
Batch index
20 00
O mesmo pode ser facilmente decodificado utilizando o seguinte proto file disponibilizado em alexbakker e a aplicação protoc
instalável em Debian com sudo apt-get install protobuf-compiler
O arquivo *.proto
contém a definição do pacote de bytes e torna possível a extração dos dados segundo seus tipos definidos neste arquivo de esquema.
Arquivo: migration.proto
syntax = "proto3";
message MigrationPayload {
enum Algorithm {
ALGORITHM_UNSPECIFIED = 0;
ALGORITHM_SHA1 = 1;
ALGORITHM_SHA256 = 2;
ALGORITHM_SHA512 = 3;
ALGORITHM_MD5 = 4;
}
enum DigitCount {
DIGIT_COUNT_UNSPECIFIED = 0;
DIGIT_COUNT_SIX = 1;
DIGIT_COUNT_EIGHT = 2;
}
enum OtpType {
OTP_TYPE_UNSPECIFIED = 0;
OTP_TYPE_HOTP = 1;
OTP_TYPE_TOTP = 2;
}
message OtpParameters {
bytes secret = 1;
string name = 2;
string issuer = 3;
Algorithm algorithm = 4;
DigitCount digits = 5;
OtpType type = 6;
int64 counter = 7;
}
repeated OtpParameters otp_parameters = 1;
int32 version = 2;
int32 batch_size = 3;
int32 batch_index = 4;
int32 batch_id = 5;
}
e agora chamando tudo junto na linha de comando do terminal
$ echo -ne "${data}" | base64 -d | protoc --decode=MigrationPayload --proto_path=./ migration.proto
produz-se uma saída mais amigável
otp_parameters {
secret: "\3610g\232\272\203\315(\253\337\021E\t\303\332"
name: "_Ficticious_Name:[email protected]"
issuer: "Issuer_Companye"
algorithm: ALGORITHM_SHA1
digits: DIGIT_COUNT_SIX
type: OTP_TYPE_TOTP
}
version: 1
batch_size: 1
Aqui a chave secreta, com apenas 15 bytes, é dada numa sequência de caracteres ASCII e códigos em base octal para aqueles caracteres não imprimíveis.
Ideias
A chave secreta pode então ser utilizada em outras aplicações standalone [1], online [2], [3], embarcadas em microcontroladores [4], entre outras possibilidades para geração dos tokens TOTP. Deve-se considerar o mesmo algoritmo hash e quantidade de dígitos sendo que a chave secreta jamais deve ser revelada. Se implementado em um microcontrolador, escolher dispositivos que possuam trava lógica anticópia do seu firmware.
Lições revisadas
- TOTP, HOTP
- Protobuf
- BASE32, BASE64
Siglas utilizadas
TOTP = Time-Based One-Time Password
HOTP = HMAC-Based One-Time Password
HMAC = Hashed Message Authentication Code
Esse pequeno reporte apresentou uma solução ligeiramente diferente em comparação ao conteúdo de uma matéria publicada no Medium recentemente. Espera-se que o conteúdo apresentado seja útil para quem já teve a mesma curiosidade, seja para entender esses recursos utilizados em 2FA ou mesmo implementar soluções independentes de bibliotecas de terceiros para suas aplicações online ou standalone embarcadas.
Post-Scriptum: Após postar este conteúdo encontrei mais uma postagem aqui no Tabnews criada há cerca de dois anos.
[Keywords: HOTP, migration, QR-Code, token, TOTP] // for [index|filter]ing purposes