Esse artigo foi escrito por: Muriel Pinho e traduzido por Dimitris Calixto, artigo original disponível aqui
Notas criptografadas é um dapp experimental para a criação e armazenamento de informação confidencial sob a forma de pequenos pedaços de texto. O usuário pode acessar suas notas através de qualquer número de dispositivos automaticamente sincronizados e autenticados através da Internet Identity. Graças à encriptação end-to-end realizada pelo frontend do dapp, o usuário não precisa confiar no backend do dapp.
Você pode brincar com o dapp implementado no IC e ver uma rápida introdução no YouTube.
Ideia
Nós queríamos construir um exemplo simples (mas não tão simples) de um dapp funcionando puramente no IC. Este exemplo baseia-se nas capacidades de serviço e armazenamento do IC na Internet. Nós nos concentramos nas duas características chaves para o nosso exemplo de dapp: (1) encriptação end-to-end do lado do cliente e (2) suporte multiusuário e multi-dispositivo.
Para demonstrar o potencial do IC como plataforma para desenvolver essas dapps, implementamos este exemplo utilizando dois kits de desenvolvimento Cânister (CDKs) distintos. O CDK Motoko permite aos criadores implementar dapps baseados em atores usando a linguagem Motoko. O CDK Rust permite a implementação de dapps em Rust. Em ambos os casos, os cânisters são compilados em arquivos WebAssembly que são depois implantados no IC.
Abordagem
A funcionalidade básica das Notas Criptografadas é constituída por dois componentes principais.
Primeiro, reutilizamos o código de um dapp (não encriptado) chamado IC-Notes. Em particular, o IC-Notes baseia-se na Internet Identity (II) cânister para autenticação do usuário, uma abordagem que também é herdada pelas Notas Criptografadas. Para fins de desenvolvimento, implementamos uma instância local do cânister II (juntamente com uma instância local de Notas Criptografadas); ao implantar Notas Criptografadas na rede principal, a instância real de II é utilizada para autenticação.
Em segundo lugar, ativamos o lado do cliente, encriptação end-to-end para o conteúdo da nota, tomando emprestado a solução de outro dapp existente chamado IC-Vault. Nossa nota Criptografada segue a abordagem do IC-Vault para suportar o gerenciamento de vários dispositivos.
No contexto dos cânisters discutidos neste documento, um dispositivo não é necessariamente um dispositivo físico separado, mas um dispositivo lógico de instância, por exemplo, um navegador web, com o seu próprio armazenamento local de dados. Por exemplo, consideramos dois navegadores web que funcionam no mesmo notebook como dois dispositivos independentes; estes navegadores geram as suas próprias chaves de encriptação. Em contraste, o II cânister depende de chaves de encriptação geradas por hardware, distinguindo apenas os dispositivos de hardware.
Para suportar múltiplos dispositivos por usuário, o IC-Vault emprega um gestor de dispositivos, um cânister que sincroniza com segurança chaves específicas do dispositivo em todos os dispositivos que estão associados a um usuário. O resto deste documento foca no cânister de Notas Criptografadas que implementa um gestor de dispositivos de forma semelhante, mas como parte do seu cânister principal.
Para mais detalhes e histórias dos usuários, consulte o arquivo README.
Gestão de notas
- Os usuários são ligados a II no frontend, obtendo o usuário um princípio que pode ser utilizado para chamar consultas e atualizações de API.
- Internamente, armazenamos o mapa do formulário
Principal → [Notas]
e umcounter
- O
counter
armazena o número de notas que o cânister criou (em todos os principais). - O método
create
adiciona uma nota à entrada do seu principal (se existir), ou adiciona o principal ao mapa com anote_id == counter
, e depois incrementa ocounter
. - O método
update
puxa uma nota, para o chamado principal e para anote_id
fornecida e substitui-a pelotext
fornecido (estetext
é suposto ser encriptado pelo frontend). - O método
delete
encontra a nota com onote_id
dado no mapa e o remove . Para assegurar que os IDs das notas são sempre globalmente únicos, não diminuímos ocounter
.
Criptografia
- A encriptação de notas é inteiramente do lado do cliente. No entanto, o nosso dapp de exemplo ainda não está protegido contra ataques potencialmente reveladores de dados por um fornecedor de nós possivelmente malicioso. Por exemplo, o atacante pode inferir quantas notas tem um determinado usuário, estatísticas de atividade do usuário, etc. Portanto, por favor leia cuidadosamente o termo de responsabilidade antes de utilizar qualquer código ou padrão deste dapp.
- Recorde que, na nossa definição, um dispositivo não é necessariamente um dispositivo físico separado, mas simplesmente uma instância de navegador web com um armazenamento local independente.
- O dapp usa três tipos diferentes de chaves:
- Chave secreta simétrica AES-GCM: utilizada para encriptar as notas de um determinado mandante. As notas de um mandante são armazenadas na cânister de Notas Criptografadas com esta chave secreta. Assim, o frontend do dapp precisa conhecer esta chave secreta para desencriptar as notas deste usuário e enviar notas encriptadas para serem armazenadas no cânister de Notas Criptografadas.
- Chave pública do dispositivo RSA-OAEP: utilizada para encriptar a chave secreta simétrica AES do mandante. A chave secreta encriptada é armazenada no cânister para cada dispositivo registrado junto do principal. A mesma chave é utilizada para diferentes mandantes que utilizam esse dispositivo.
- Dispositivo RSA-OAEP chave privada: utilizado para desencriptar a chave secreta simétrica AES armazenada na caixa de Notas Criptografadas para um determinado mandante. Uma vez que o frontend descriptografar a chave secreta, pode utilizar esta chave para descriptografar as notas armazenadas no cânister de Notas Encriptadas.
-
Armazenamos um mapa do formulário:
Principal → (DeviceAlias → PublicKey, DeviceAlias → CipherText)
Este mapa é utilizado para a gestão de dispositivos do usuário, como se explica a seguir.
Para registar um dispositivo, o frontend gera um pseudónimo de dispositivo, uma chave pública, e uma chave privada (guardada no seu armazenamento local).
Adicionando um dispositivo:
Registro do dispositivo: Se esta identidade já for conhecida, um novo dispositivo permanecerá no início não sincronizado; neste momento, apenas o
alias
e apublickey
deste dispositivo será adicionado ao cânister de Notas Criptografadas.Sincronização do dispositivo: Quando um dispositivo não sincronizado obtém a lista de todos os dispositivos não sincronizados para este II, encriptará a chave secreta AES simétrica sob a chave pública de cada dispositivo não sincronizado. Posteriormente, o dispositivo não sincronizado obtém a chave secreta AES simétrica encriptada, decripta, e depois utiliza-a para descriptografar as notas existentes armazenadas na cânister de Notas Criptografadas.
Uma vez autenticado com II:
Se esta identidade não for conhecida, então o frontend gera uma chave secreta AES simétrica e encripta com a sua própria chave pública. Então o frontend chama a
seed (publickey, ciphertext)
, adicionando ao mapa esse texto cifrado e a suapublickey
associada.Se um usuário quiser registrar um dispositivo subsequente, o frontend chama
register_device
, passando noalias
epublickey
desse dispositivo. O frontend chama entãosubmit_ciphertexts([publickey, ciphertext])
para todos os dispositivos que precisam registrar. Isto permite aos dispositivos registrados puxar e decifrar a chave AES para encriptar e decifrar as notas do usuário.
Top comments (0)