Implementando Criptografia End-to-End (E2E) em um Chat com Go

Implementando Criptografia End-to-End (E2E) em um Chat com Go

Este artigo detalha a implementação de criptografia End-to-End (E2E) em um chat simples utilizando a linguagem Go. Abordaremos desde os conceitos teóricos de criptografia simétrica e assimétrica até a aplicação prática com ECDH e AES, demonstrando como garantir a segurança e a privacidade das comunicações.

MundiX News·29 de junho de 2026·15 min de leitura·👁 1 views

Olá, Habr! Neste artigo, vamos implementar a criptografia E2E em um chat simples como exemplo prático. Continuando nossa série sobre desenvolvimento de rede em Go, na edição anterior, construímos um chat TCP básico onde as mensagens trafegavam em texto puro, tornando-as vulneráveis a interceptações. Agora, vamos adicionar criptografia para garantir a segurança na troca de dados.

Um Pouco de Teoria

Este guia foca na compreensão e aplicação prática, sem aprofundar nos complexos aspectos matemáticos da criptografia. Nosso objetivo é a implementação de engenharia. Para começar, precisamos entender três conceitos fundamentais:

  • Criptografia Simétrica: Utiliza a mesma chave secreta para criptografar e descriptografar dados. É rápida e ideal para grandes volumes de informação. O principal desafio é como transferir essa chave de forma segura pela internet, evitando interceptações.
  • Criptografia Assimétrica: Resolve o problema da transferência de chaves. Cada usuário possui um par de chaves: uma pública (usada para criptografar e compartilhada abertamente) e uma privada (usada para descriptografar e mantida em segredo).
  • Criptografia de Curva Elíptica (ECC / ECDH): Um tipo moderno de criptografia assimétrica baseado em matemática complexa de pontos em curvas. Suas vantagens incluem velocidade significativamente maior que o RSA e chaves muito menores para o mesmo nível de segurança (apenas 32 bytes para X25519 contra 4096 bits do RSA). Utilizaremos o protocolo ECDH (Elliptic Curve Diffie-Hellman), que permite que duas partes, conhecendo as chaves públicas uma da outra, calculem um segredo compartilhado comum sem trocá-lo diretamente pela rede.

O Processo Simplificado:

  1. O cliente gera uma chave AES (para criptografia simétrica) e um par de chaves ECDH (privada e pública).
  2. As chaves públicas ECDH são trocadas entre os usuários. Cada um, usando sua chave privada e a chave pública do outro, calcula uma chave mestra compartilhada.
  3. Utilizando a chave mestra, cada usuário criptografa sua chave AES e a envia ao interlocutor.
  4. Após a troca das chaves simétricas, cada participante descriptografa a chave AES do outro.
  5. Ao enviar uma mensagem, o usuário a criptografa com sua chave AES, que o destinatário já possui. O destinatário, então, descriptografa a mensagem com a mesma chave.

Implementando o Cliente

Anteriormente, focamos na parte do servidor e usamos telnet como cliente. Agora, desenvolveremos a lógica do cliente:

go
type ClientChat struct {
	Address       string
	Conn          net.Conn
}

func NewClientChat(Addr string) *ClientChat {
	return &ClientChat{
		Address:       Addr,
	}
}

Conectando ao host:

go
func (c *ClientChat) Start() {
	var err error
	c.Conn, err = net.Dial("tcp", c.Address)
	if err != nil {
		log.Fatal("Failed connection: %w", err)
	}
	defer c.Conn.Close()

	c.enterToChat()
	go c.readLoop()

	scanner := bufio.NewScanner(os.Stdin)
	for scanner.Scan() {
		text := scanner.Text()
		if text == "" {
			continue
		}

		// Lógica de processamento de entrada
	}

	if err := scanner.Err(); err != nil {
		log.Printf("Failed read from console: %v", err)
	}
}

Agora, vamos complementar a estrutura do cliente para armazenar suas próprias chaves e as chaves dos interlocutores:

go
type CryptoKeys struct {
	PublicECDHKey  []byte
	PrivateECDHKey []byte
	AESKey         []byte
}

type P2PKeys struct {
	SecretECDH []byte
	AES        []byte
}

type ClientChat struct {
	Address       string
	Conn          net.Conn
	Keys          cryptography.CryptoKeys
	TopologyTable map[string]P2PKeys
}

Criamos uma tabela hash (TopologyTable) onde a chave é o endereço do usuário e o valor contém a chave mestra ECDH para troca de chaves simétricas e a própria chave simétrica do usuário.

Em seguida, desenvolvemos as funções criptográficas:

Geração da Chave Mestra Comum:

go
func GenarateECDHSecret(privateKey []byte, publicKey []byte) []byte {
	curve := ecdh.X25519()

	myPrivateKey, _ := curve.NewPrivateKey(privateKey)
	peerPublicKey, _ := curve.NewPublicKey(publicKey)

	sharedSecret, _ := myPrivateKey.ECDH(peerPublicKey)
	aesKey := sha256.Sum256(sharedSecret)

	return aesKey[:]
}

Criptografia da Nossa Chave Simétrica:

go
func EncryptAESKey(secretShared []byte, aesKey []byte) []byte {
	block, _ := aes.NewCipher(secretShared)
	aesGCM, _ := cipher.NewGCM(block)

	nonce := make([]byte, aesGCM.NonceSize())
	io.ReadFull(rand.Reader, nonce)

ciphertext := aesGCM.Seal(nonce, nonce, aesKey, nil)

	return ciphertext
}

Por que usar GCM?

O modo GCM (Galois/Counter Mode) é um modo de criptografia autenticada (AEAD - Authenticated Encryption with Associated Data). Ele realiza duas tarefas:

  1. Criptografa a aesKey usando a chave compartilhada e um nonce aleatório.
  2. Gera uma tag de autenticidade de 16 bytes combinando o texto cifrado, o nonce e a chave secreta. Isso protege o pacote contra modificações durante a transmissão.

A estrutura resultante é: [Nonce de 12 bytes] + [Chave criptografada] + [Tag de 16 bytes].

Descriptografia da Chave do Remetente:

go
func DecryptSenderKey(secretShared []byte, ciphertextWithNonce []byte) ([]byte, error) {
	block, _ := aes.NewCipher(secretShared)
	aesGCM, _ := cipher.NewGCM(block)

	nonceSize := aesGCM.NonceSize()
	if len(ciphertextWithNonce) < nonceSize {
		return nil, fmt.Errorf("ciphertext too short")
	}

	nonce := ciphertextWithNonce[:nonceSize]
	actualCiphertext := ciphertextWithNonce[nonceSize:]

	aesKey, err := aesGCM.Open(nil, nonce, actualCiphertext, nil)
	if err != nil {
		return nil, fmt.Errorf("failed to decrypt or authenticate: %w", err)
	}

	return aesKey, nil
}

Criptografia e Descriptografia de Mensagens:

go
func EncryptMessage(key []byte, plaintext []byte) ([]byte, error) {
	block, err := aes.NewCipher(key)
	if err != nil {
		return nil, fmt.Errorf("failed to create cipher: %w", err)
	}

	aesGCM, err := cipher.NewGCM(block)
	if err != nil {
		return nil, fmt.Errorf("failed to create gcm: %w", err)
	}

	nonce := make([]byte, aesGCM.NonceSize())
	if _, err = io.ReadFull(rand.Reader, nonce); err != nil {
		return nil, fmt.Errorf("failed to generate nonce: %w", err)
	}

	ciphertext := aesGCM.Seal(nonce, nonce, plaintext, nil)

	return ciphertext, nil
}

func DecryptMessage(key []byte, ciphertextWithNonce []byte) ([]byte, error) {
	block, err := aes.NewCipher(key)
	if err != nil {
		return nil, fmt.Errorf("failed to create cipher: %w", err)
	}

	aesGCM, err := cipher.NewGCM(block)
	if err != nil {
		return nil, fmt.Errorf("failed to create gcm: %w", err)
	}

	nonceSize := aesGCM.NonceSize()
	if len(ciphertextWithNonce) < nonceSize {
		return nil, fmt.Errorf("ciphertext too short")
	}

	nonce := ciphertextWithNonce[:nonceSize]
	actualCiphertext := ciphertextWithNonce[nonceSize:]

	plaintext, err := aesGCM.Open(nil, nonce, actualCiphertext, nil)
	if err != nil {
		return nil, fmt.Errorf("failed to decrypt (fake tag or wrong key): %w", err)
	}

	return plaintext, nil
}

Para gerenciar a comunicação entre os usuários, precisamos das seguintes estruturas de pacote:

go
const (
	TypeAuth        = "AUTH" 
	TypePeerList    = "PEER_LIST" 
	TypeNewPeer     = "NEW_PEER" 
	TypeGetPeerList = "GET_PEER_LIST" 
	TypeSenderKey   = "SENDER_KEY" 
	TypeChatMsg     = "CHAT_MSG" 
)

type Message struct {
	Author string `json:"author"`
	Text   string `json:"text"`
}

type PeerInfo struct {
	Nickname  string `json:"nickname"`
	PublicKey []byte `json:"public_key"`
}

type Packet struct {
	Type       string     `json:"type"`
	YourName   string     `json:"your_name"` // Campo para filtrar pacotes próprios
	FromPeer   string     `json:"from_peer,omitempty"`
	PublicKey  []byte     `json:"public_key,omitempty"`
	TargetPeer string     `json:"target_peer,omitempty"`
	EncAESKey  []byte     `json:"enc_aes_key,omitempty"`
	Peers      []PeerInfo `json:"peers,omitempty"`
	Message    []byte     `json:"message,omitempty"`
}
  • TypeAuth: Enviado pelo cliente ao conectar, contendo sua chave pública ECDH para registro no servidor.
  • TypePeerList: Enviado pelo servidor ao novo cliente em resposta à autenticação, listando todos os participantes ativos e suas chaves públicas.
  • TypeNewPeer: Enviado pelo servidor a todos os usuários existentes para notificar a conexão de um novo usuário e compartilhar sua chave pública.
  • TypeGetPeerList: Requisição do cliente ao servidor para atualizar a lista de participantes (usado como fallback se a tabela de topologia estiver dessincronizada).
  • TypeSenderKey: Enviado entre clientes via servidor, contendo a chave AES do remetente criptografada com o segredo ECDH compartilhado para o destinatário específico.
  • TypeChatMsg: Pacote com a mensagem de texto. O conteúdo (Message) é criptografado com a chave AES do remetente, e o servidor apenas o retransmite.

Funções auxiliares para criação de pacotes:

go
func NewPeerPacket(publicKey []byte) *message.Packet {
	return &message.Packet{
		Type:      message.TypeAuth,
		PublicKey: publicKey,
	}
}

func ProcessedNewPeer(newPeerPacket message.Packet, privateKey []byte, aesKey []byte) *message.Packet {
	secret := cryptography.GenarateECDHSecret(privateKey, newPeerPacket.PublicKey)
	cryptAES := cryptography.EncryptAESKey(secret, aesKey)

	packet := message.Packet{
		Type:       message.TypeSenderKey,
		EncAESKey:  cryptAES,
		TargetPeer: newPeerPacket.FromPeer,
	}

	return &packet
}

func CreateSenderKeyPacket(cryptoAES []byte, target string) *message.Packet {
	return &message.Packet{
		Type:       message.TypeSenderKey,
		TargetPeer: target,
		EncAESKey:  cryptoAES,
	}
}

Geração das Chaves do Cliente:

go
func GenerateClientsCrypto() *CryptoKeys {
	privateKey, err := ecdh.X25519().GenerateKey(rand.Reader)
	if err != nil {
		log.Fatalf("failed generate private key: %v", err)
	}

	publicKey := privateKey.PublicKey()

	myAESKey := make([]byte, 32)

	_, err = rand.Read(myAESKey)
	if err != nil {
		log.Fatalf("failed generate AES key: %v", err)
	}

	return &CryptoKeys{
		PublicECDHKey:  publicKey.Bytes(),
		PrivateECDHKey: privateKey.Bytes(),
		AESKey:         myAESKey,
	}
}

Lógica de Leitura do Cliente:

go
func (c *ClientChat) readLoop() {
	scanner := bufio.NewScanner(c.Conn)
	for scanner.Scan() {
		var packet message.Packet
		if err := json.Unmarshal(scanner.Bytes(), &packet); err != nil {
			log.Printf("Error parsing packet: %v", err)
			continue
		}

		c.processPacket(packet)
	}
}

O cliente lê o fluxo de pacotes enviados pelo servidor e os processa:

Processamento de Pacotes:

go
func (c *ClientChat) processPacket(packet message.Packet) error {
	switch packet.Type {

	case message.TypeNewPeer:
		if packet.FromPeer == packet.YourName {
			c.addAES(packet.FromPeer, c.Keys.AESKey)
			return nil
		}

		fmt.Printf(" [System]: User %s enter to chat.\n", packet.FromPeer)
		sendKeyPacket := processedpacket.ProcessedNewPeer(packet, c.Keys.PrivateECDHKey, c.Keys.AESKey)

		secretECDH := cryptography.GenarateECDHSecret(c.Keys.PrivateECDHKey, packet.PublicKey)
		c.addECDH(packet.FromPeer, secretECDH)

		c.sendMessage(*sendKeyPacket)

	case message.TypeSenderKey:
		peerKeys := c.getP2PKeys(packet.FromPeer)
		aesKey, err := cryptography.DecryptSenderKey(peerKeys.SecretECDH, packet.EncAESKey)
		if err != nil {
			log.Printf("Failed decrypt aes: %v", err)
			return err
		}

		c.addAES(packet.FromPeer, aesKey)

	case message.TypeChatMsg:
		keys := c.getP2PKeys(packet.FromPeer)

		decryptMessage, _ := cryptography.DecryptMessage(keys.AES, packet.Message)

		var msg message.Message
		if err := json.Unmarshal(decryptMessage, &msg); err != nil {
			log.Printf("Failed decode message: %v\n", err)
			return err
		}
		fmt.Printf("[%s]: %s\n", packet.FromPeer, msg.Text)

	case message.TypePeerList:
		c.createTopologyTable(packet.Peers)
		c.BroadcastAES()

	default:
		log.Printf("incorrect packet type: %s", packet.Type)
		return fmt.Errorf("incorrect packet type: %s", packet.Type)
	}

	return nil
}
  • TypeNewPeer: Quando um novo usuário entra, o cliente gera a chave mestra ECDH com o novo usuário, criptografa sua chave AES e a envia. A chave mestra é armazenada localmente.
  • TypeSenderKey: Ao receber a chave AES criptografada, o cliente usa a chave mestra ECDH armazenada para descriptografá-la e salvá-la para comunicação futura com aquele usuário.
  • TypeChatMsg: A mensagem recebida é descriptografada usando a chave AES correspondente ao remetente, que já deve estar disponível localmente.
  • TypePeerList: O cliente processa a lista de participantes recebida do servidor, inicializando a tabela de topologia e transmitindo sua chave AES para os outros.

Métodos Auxiliares do Cliente:

  • enterToChat(): Envia um pacote AUTH com a chave pública ECDH para iniciar o handshake.
  • createTopologyTable(peers): Inicializa a tabela de topologia com as chaves públicas recebidas, calculando os segredos ECDH compartilhados.
  • BroadcastAES(): Envia a chave AES do cliente para todos os outros participantes, criptografada com os segredos ECDH correspondentes.
  • getP2PKeys(user): Recupera as chaves ECDH e AES para um determinado usuário, solicitando uma atualização da lista ao servidor se necessário.
  • getTopologyTable(): Solicita ao servidor uma atualização da lista de participantes.
  • sendMessage(packet): Serializa um pacote em JSON e o envia via TCP.
  • addECDH(user, ecdhKey): Adiciona ou atualiza o segredo ECDH para um usuário na TopologyTable.
  • addAES(user, aesKey): Adiciona ou atualiza a chave AES para um usuário na TopologyTable.

Ajustando o Servidor

O servidor precisa armazenar as chaves públicas dos usuários, processar pacotes e gerenciar o handshake:

go
type Peer struct {
	Conn        net.Conn
	PublicKey   []byte
	ConnectedAt time.Time
}

type Server struct {
	Address      string
	Listener     net.Listener
	clients      map[string]*Peer
	deadClients  []net.Conn
	mu           sync.RWMutex
	messagesChan chan message.Packet
}

A estrutura Peer agora inclui a chave pública do cliente. O canal messagesChan será usado para transmitir pacotes.

Handshake e Registro do Usuário:

go
func (s *Server) handleConn(conn net.Conn) {
	defer conn.Close()

	err := s.handshake(conn)
	if err != nil {
		return
	}

	buf := make([]byte, 2048)
	for {
		n, err := conn.Read(buf)
		if err != nil {
			log.Printf("Connection error: %v", err)
			return
		}

		var packet message.Packet
		err = json.Unmarshal(buf[:n], &packet)
		if err != nil {
			log.Printf("Failed encoding packet: %v", err)
			continue
		}

		packet.FromPeer = conn.RemoteAddr().String()

		s.processPacket(packet)
	}
}

func (s *Server) handshake(conn net.Conn) error {
	if _, exists := s.clients[conn.RemoteAddr().String()]; exists {
		conn.Close()
		return fmt.Errorf("user already connection")
	}

	buf := make([]byte, 2048)
	n, err := conn.Read(buf)
	if err != nil {
		log.Printf("Handshake error: %v", err)
		return fmt.Errorf("failed handshake: %w", err)
	}

	var packet message.Packet
	err = json.Unmarshal(buf[:n], &packet)
	if err != nil {
		log.Printf("Handshake error: %v", err)
		return fmt.Errorf("failed handshake: %v", err)
	}

	if packet.Type != message.TypeAuth {
		log.Printf("Incorrect type packet")
		return fmt.Errorf("client hello packet need auth type")
	}

	s.registerPeer(conn, packet.PublicKey)

	packet.Type = message.TypeNewPeer
	packet.FromPeer = conn.RemoteAddr().String()
	s.processPacket(packet)

	packetListPeers := s.generatePacketListPeers(conn.RemoteAddr().String())
	s.processPacket(*packetListPeers)

	return nil
}

Durante o handshake, o servidor aguarda o pacote AUTH, registra o novo usuário com sua chave pública, envia um pacote NEW_PEER e, em seguida, um PEER_LIST com todos os participantes ativos.

Geração do Pacote de Lista de Participantes:

go
func (s *Server) generatePacketListPeers(target string) *message.Packet {
	var packet message.Packet

	packet.TargetPeer = target
	packet.Type = message.TypePeerList

	peersInfo := make([]message.PeerInfo, 0, len(s.clients))
	s.mu.Lock()
	for peer, data := range s.clients {
		if peer != target {
			peersInfo = append(peersInfo, message.PeerInfo{
				Nickname:  peer,
				PublicKey: data.PublicKey,
			})
		}
	}
	s.mu.Unlock()

	packet.Peers = peersInfo

	return &packet
}

Processamento de Pacotes no Servidor:

go
func (s *Server) processPacket(packet message.Packet) error {
	switch packet.Type {
	case message.TypeNewPeer, message.TypeChatMsg:
		s.messagesChan <- packet
	case message.TypePeerList, message.TypeSenderKey:
		targetConn, exists := s.getPeerConn(packet.TargetPeer)
		if !exists {
			log.Printf("not found target connection")
			return fmt.Errorf("not found target connection")
		}
		s.writeInConnection(targetConn, packet)
	case message.TypeGetPeerList:
		packetList := s.generatePacketListPeers(packet.FromPeer)
		targetConn, exists := s.getPeerConn(packet.TargetPeer) // Note: TargetPeer here is likely incorrect, should be FromPeer
		if !exists {
			log.Printf("not found target connection")
			return fmt.Errorf("not found target connection")
		}
		s.writeInConnection(targetConn, *packetList)

	default:
		return fmt.Errorf("incorrect packet type")
	}

	return nil
}
  • Pacotes NEW_PEER e CHAT_MSG são enviados para o canal messagesChan para broadcast.
  • Pacotes PEER_LIST e SENDER_KEY, direcionados a um usuário específico, são encaminhados diretamente para a conexão do destinatário.
  • GET_PEER_LIST aciona a geração e envio de uma lista de participantes para o remetente.

Testando a Implementação

Ao conectar dois clientes e enviar uma mensagem, o servidor registrará um erro ao tentar decodificar a mensagem de chat, pois ela está criptografada. No entanto, os clientes conseguirão trocar mensagens criptografadas com sucesso.

Exemplo de Saída do Cliente:

─$ go run cmd/client/main.go
Hello world!
[[::1]:35176]: Hello world!

Exemplo de Saída do Servidor (com erro de decodificação):

└─$ go run cmd/server/main.go
2026/06/28 20:35:01 Server started
2026/06/28 20:35:04 Welcome, [::1]:56122
2026/06/28 20:35:08 Welcome, [::1]:56126
2026/06/28 20:35:12 failed decode message on server side: invalid character 'B' looking for beginning of value
2026/06/28 20:35:12 message byte: [66 118 215 94 9 164 135 205 93 184 98 52 117 159 67 10 187 128 100 149 226 36 107 89 162 153 217 94 103 29 239 219 126 9 228 218 119 54 195 208 128 194 140 213 22 216 245 239 45 3 91 2 159 88 91 44 117 195 53 166 138 86 89]

Este exemplo demonstra com sucesso a implementação da criptografia End-to-End (E2E) em um chat, garantindo a confidencialidade das comunicações.

Código Principal do Cliente:

go
package client

import (
	"bufio"
	"encoding/json"
	"fmt"
	"log"
	"net"
	"os"

	cryptography "github.com/barashF/TCP-chat/crypto"
	"github.com/barashF/TCP-chat/message"
	processedpacket "github.com/barashF/TCP-chat/processed_packet"
)

type P2PKeys struct {
	SecretECDH []byte
	AES        []byte
}

type ClientChat struct {
	Address       string
	Conn          net.Conn
	Keys          cryptography.CryptoKeys
	TopologyTable map[string]P2PKeys
}

func NewClientChat(Addr string) *ClientChat {
	return &ClientChat{
		Address:       Addr,
		Keys:          *cryptography.Gener
🛡️⚡

Pare de pesquisar. Comece a hackear.

O MundiX é seu copiloto de pentest com IA: comandos exatos, análise de outputs e próximo passo na kill chain — em segundos.

Testar grátis por 7 dias →

Sem cartão para começar · Planos a partir de R$49/mês

📤 Compartilhar & Baixar

🧰 Ferramentas recomendadas

Divulgação: alguns links são patrocinados. Podemos receber comissão se você comprar — sem custo extra para você. Só indicamos o que faz sentido para a comunidade.

Aprendendo Kali Linux: Teste de segurança, pentest e hacking ético

Aprendendo Kali Linux: Teste de segurança, pentest e hacking ético

Com centenas de ferramentas pré-instaladas, a distribuição Kali Linux facilita o trabalho de os profissionais de segurança começarem a fazer testes de segurança rapidamente. No entanto, com mais de 600 ferramentas em seu arsenal, o Kali Linux também pode ser desafiador. A nova edição deste prático livro abrange as atualizações nas ferramentas e inclui uma melhor abordagem da análise forense e da engenharia reversa. Ric Messier, autor, não fica apenas no teste de segurança, mas também faz uma abordagem sobre a execução de análise forense, incluindo a análise em disco e na memória, assim como alguma análise básica de malware. • Explore as diversas ferramentas disponíveis no Kali Linux • Entenda o valor do teste de segurança e examine os tipos de teste disponíveis • Aprenda os aspectos básicos do pentest em todo o ciclo de vida do ataque • Instale o Kali Linux em vários sistemas, tanto físicos quanto virtuais • Descubra como usar diferentes ferramentas destinadas à segurança • Estruture um teste de segurança baseado nas ferramentas do Kali Linux • Estenda as ferramentas do Kali para criar técnicas de ataque avançadas • Use o Kali Linux para ajudar a criar relatórios quando o teste terminar “A abordagem concisa, clara e baseada na experiência adotada por Ric Messier para a introdução do Kali Linux e dos testes de cibersegurança é incomparável. Este livro é uma leitura excelente e acessível para iniciantes e um recurso valioso para qualquer pessoa.” —Alexander Arlt, Consultor sênior de segurança, Google

Ver na Amazon
Gshield 2 em 1 Hub Extensor Conector USB-C + USB-A e Adaptador de Rede Ethernet LAN RJ45 com 3 Entradas USB 3.0 até 5 Gbps em Liga de Alumínio para Computador e Notebook, Cinza

Gshield 2 em 1 Hub Extensor Conector USB-C + USB-A e Adaptador de Rede Ethernet LAN RJ45 com 3 Entradas USB 3.0 até 5 Gbps em Liga de Alumínio para Computador e Notebook, Cinza

Compatível com portas USB-C e USB-A, ideal para ampliar a conectividade de dispositivos como MacBook Pro e outros com portas USB-C. Inclui um adaptador USB-A extra, proporcionando uma conexão Ethernet estável e veloz de até 1 Gbps, perfeita para filmes, jogos online e videoconferências. Oferece três portas USB 3.0 com velocidades de transferência de até 5 Gbps, permitindo conectar mouse, teclado, discos rígidos e outros periféricos. Fabricado em alumínio durável, garantindo longa vida útil e resistência ao uso diário. Design compacto e leve, ideal para viagens de negócios e uso diário, facilitando o transporte e armazenamento. Funciona com Windows 10/8.1/8, Mac OS e Chrome OS, oferecendo versatilidade incomparável para diversas necessidades de conectividade. Assegura uma conectividade estável e rápida, perfeita para tarefas exigentes como transferência de dados, streaming e mais.

Ver na Amazon
Hacking APIs: Breaking Web Application Programming Interfaces

Hacking APIs: Breaking Web Application Programming Interfaces

Hacking APIs is a crash course on web API security testing that will prepare you to penetration-test APIs, reap high rewards on bug bounty programs, and make your own APIs more secure. You'll learn how REST and GraphQL APIs work in the wild and set up a streamlined API testing lab with Burp Suite and Postman. Then you'll master tools useful for reconnaissance, endpoint analysis, and fuzzing, such as Kiterunner and OWASP Amass. Next, you'll learn to perform common attacks, like those targeting an API's authentication mechanisms and the injection vulnerabilities commonly found in web applications. You'll also learn techniques for bypassing protections against these attacks. In the book's nine guided labs, which target intentionally vulnerable APIs, you'll practice: Enumerating APIs users and endpoints using fuzzing techniques Using Postman to discover an excessive data exposure vulnerability Performing a JSON Web Token attack against an API authentication process Combining multiple API attack techniques to perform a NoSQL injection Attacking a GraphQL API to uncover a broken object level authorization vulnerability

Ver oferta
Gray Hat Hacking: The Ethical Hacker's Handbook, Sixth Edition

Gray Hat Hacking: The Ethical Hacker's Handbook, Sixth Edition

Up-to-date strategies for thwarting the latest, most insidious network attacks This fully updated, industry-standard security resource shows, step by step, how to fortify computer networks by learning and applying effective ethical hacking techniques. Based on curricula developed by the authors at major security conferences and colleges, the book features actionable planning and analysis methods as well as practical steps for identifying and combating both targeted and opportunistic attacks. Gray Hat Hacking: The Ethical Hacker's Handbook, Sixth Edition clearly explains the enemy's devious weapons, skills, and tactics and offers field-tested remedies, case studies, and testing labs. You will get complete coverage of Internet of Things, mobile, and Cloud security along with penetration testing, malware analysis, and reverse engineering techniques. State-of-the-art malware, ransomware, and system exploits are thoroughly explained. Fully revised content includes 7 new chapters covering the latest threats Includes proof-of-concept code stored on the GitHub repository Authors train attendees at major security conferences, including RSA, Black Hat, Defcon, and B-Sides

Ver na Amazon
Bloqueador USB de privacidade de porta USB para PC, notebook, bloco de laptop,

Bloqueador USB de privacidade de porta USB para PC, notebook, bloco de laptop,

Proteção de privacidade aprimorada: protege o link de transmissão de dados para evitar roubo de informações, fornecendo proteção de segurança robusta que protege a privacidade do usuário durante transferências de arquivos e garante uma conexão segura para interações de dispositivos sem preocupações em vários ambientes Uso a longo prazo: a camada protetora resistente ao desgaste, combinada com um corpo de metal resistente, oferece gerenciamento de calor confiável e qualidade duradoura durante o uso diário Entrega eficiente de energia: a tecnologia de chip inteligente garante a identificação automática dos requisitos de energia, fornecendo carregamento eficiente alinhando-se com vários protocolos de carregamento rápido para maior conveniência Proteção contra sobrecarga: evitando riscos de sobrecarga, este bloqueador de dados USB protege a vida útil da bateria e garante um desempenho estável, mantendo um fluxo estável de energia para melhorar a longevidade do dispositivo de forma eficaz Prático de transportar: com atenção à portabilidade, este bloqueador de dados USB oferece um design compacto que é leve e fácil de transportar, melhorando a conveniência do usuário e operação eficiente

Ver na Amazon

📩 Newsletter MundiX

Receba novidades de cibersegurança + um checklist de pentest grátis. Sem spam.

Ao assinar você concorda em receber e-mails. Cancele quando quiser.