Sistema Único Integrado de Tramitação Eletrônica baseado em chave pública estabelece uma infraestrutura segura para o intercâmbio de documentos eletrônicos entre entidades. Esse processo garante a autenticidade, integridade e não repúdio dos documentos durante todo o ciclo de tramitação eletrônica, eliminando a necessidade de compartilhamento de chaves secretas e proporcionando um ambiente seguro e confiável para a troca de informações sensíveis.
Existem muitas especulações e teorias sobre por que a NSA (Agência de Segurança Nacional dos Estados Unidos) teria espionado o Brasil durante os governos de Lula e Dilma Rousseff. No entanto, a verdadeira motivação por trás dessas ações não é conhecida com certeza.
Alguns afirmam que a espionagem era parte de um esforço mais amplo para monitorar líderes e governos em todo o mundo, incluindo aliados dos EUA. Outros sugerem que havia preocupações específicas com as políticas do governo brasileiro em áreas como comércio, segurança e meio ambiente. Também se especula que a espionagem possa ter sido usada para obter vantagens comerciais ou para apoiar as atividades de empresas americanas.
Independentemente da motivação por trás da espionagem, é importante destacar que essas ações foram consideradas uma violação da privacidade e da soberania do Brasil, e geraram tensões diplomáticas entre os dois países.
A despeito disso, o Sistema é totalmente compatível com OpenSSL/LibreSSL/GmSSL/RHash/Mcrypt e segue as normas do ICP do Brasil, entretanto, adicionalmente oferece alternativas mais seguras, a exemplo do EdDSA e dos padrões coreano (TTAK/KS), russo (GOST) e chinês (ShangMi).
A assinatura digital é o item que identifica o remetente de uma mensagem no ambiente eletrônico. Ela permite verificar a autoria do documento e evita que ele seja alterado. Dessa maneira, garante autenticidade, integridade e confiabilidade à identidade do responsável por aquele documento – ou seja, o autor não pode negar que tenha emitido seu conteúdo.
Essa espécie de identidade digital funciona a partir de um sistema de criptografia assimétrica. Existem duas chaves:
   • Chave privada: criptografa os dados relativos à identidade da pessoa física ou jurídica e é conhecida apenas por quem está autorizado a utilizar o certificado.
   • Chave pública: serve para decodificar o documento ou transação criptografada pela chave privada.
Considerando isso, um validador de assinatura digital verificará, com a chave pública, a validade da chave privada do assinante, confirmando que a mensagem não foi alterada e que foi enviada pelo signatário.
Golang<?php // Data you want to sign (hash or file) $data = 'my data'; // Create new private and public key $private = openssl_pkey_new(array( "private_key_bits" => 2048, "private_key_type" => OPENSSL_KEYTYPE_RSA, )); $details = openssl_pkey_get_details($private); $public = openssl_pkey_get_public($details['key']); // Get private key openssl_pkey_export($private, $privkey); // Get public key $pubkey=openssl_pkey_get_details($private); $pubkey=$pubkey["key"]; // Create signature openssl_sign($data, $signature, $private, "sha256WithRSAEncryption"); echo "<pre>Signature:\n"; echo wordwrap(bin2hex($signature), 64, "\n", true); echo "\n\n"; echo $pubkey; echo "<pre />\n"; // Verify signature $ok = openssl_verify($data, $signature, $public, "sha256WithRSAEncryption"); if ($ok == 1) { echo "valid"; } elseif ($ok == 0) { echo "invalid"; } else { echo "error: ".openssl_error_string(); } ?>
package main import ( "crypto" "crypto/rand" "crypto/rsa" "crypto/sha256" "encoding/hex" "fmt" ) func main() { // Data you want to sign (hash or file) data := []byte("my data") // Create new private key privateKey, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { fmt.Println("Error generating private key:", err) return } // Get public key publicKey := &privateKey.PublicKey // Sign the data hashed := sha256.Sum256(data) signature, err := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, hashed[:]) if err != nil { fmt.Println("Error signing data:", err) return } fmt.Println("Signature:") fmt.Println(hex.EncodeToString(signature)) fmt.Println() // Verify the signature err = rsa.VerifyPKCS1v15(publicKey, crypto.SHA256, hashed[:], signature) if err == nil { fmt.Println("valid") } else { fmt.Println("invalid") } }
Gerar par de chaves assimétricas:
./edgetk -pkey keygen -bits 2048 [-prv Private.pem] [-pass "pass"] [-pub Public.pem]
Gerar solicitação de assinatura de certificado (CSR):
./edgetk -pkey req -key Private.pem [-pass "pass"] [-cert cert.csr]
Assinar CSR:
./edgetk -pkey x509 -root cacert.pem -key CA_Priv.pem -cert cert.csr CERTIFICATE.crt
Verificar a assinatura do certificado digital:
./edgetk -pkey check -cert CERTIFICATE.crt -key CA_Public.pem echo $?
Assinatura digital:
./edgetk -pkey sign -key Private.pem [-pass "pass"] < file.ext > sign.txt sign=$(cat sign.txt|awk '{print $2}') ./edgetk -pkey verify -key Public.pem -signature $sign < file.ext echo $?
Um documento assinado com certificado digital não pode ser alterado, pois seu conteúdo é selado por criptografia.
Sua integridade é o primeiro passo da verificação de assinatura, e essa avaliação ocorre em dois cenários:
   • O documento assinado foi anexado na assinatura (assinatura attached).
   • O documento original foi assinado sem que a assinatura fosse anexada (assinatura detached), o que requer informações do arquivo original e do arquivo assinado.
Com essa validação, é possível confirmar se houveram alterações não autorizadas pelo signatário após a assinatura.
E a integridade da assinatura digital? Para avaliá-la, compara-se o hash ou o resumo criptográfico do documento original com o do documento criptografado pelo assinante.
A segunda avaliação no processo realizado pelo verificador de assinatura digital é a análise do certificado digital. Ele está dentro do período de validade? Para responder à questão, compara-se a data de expiração do certificado com a data da assinatura do documento.
Go<?php // Read the certificate from file $cert = file_get_contents('CERTIFICATE.crt'); $ssl = openssl_x509_parse($cert); echo $ssl['issuer'][CN] ." "; echo $ssl['issuer'][O] ." "; echo $ssl['issuer'][OU] ." "; echo $ssl['issuer'][L] ." "; echo $ssl['issuer'][ST] ." "; echo $ssl['issuer'][street] ." "; echo $ssl['issuer'][C] ." "; echo $ssl['issuer'][postalCode] ."\n"; echo $ssl['extensions'][subjectAltName] ."\n"; echo "Valid from " . gmdate("Y-m-d\TH:i:s\Z", $ssl[validFrom_time_t]); echo " to " . gmdate("Y-m-d\TH:i:s\Z", $ssl[validTo_time_t]) ."\n"; // To print out all the array print_r(array_values($ssl)); print_r(array_keys($ssl)); print_r($cert); ?>
Linha de Comandofunc main() { // Read the certificate from file var certPEM []byte file, err := os.Open("CERTIFICATE.crt") if err != nil { log.Println(err) } info, err := file.Stat() if err != nil { log.Println(err) } buf := make([]byte, info.Size()) file.Read(buf) certPEM = buf var certPemBlock, _ = pem.Decode([]byte(certPEM)) var cert, _ = x509.ParseCertificate(certPemBlock.Bytes) var certPublicKey = cert.PublicKey.(*rsa.PublicKey) fmt.Printf("Modulus=%X\n", certPublicKey.N) // Print out the info format := "Monday, 02-Jan-06 15:04:05 MST" fmt.Printf("Expiry: %s \n", cert.NotAfter.Format(format)) fmt.Printf("Common Name: %s \n", cert.Issuer.CommonName) fmt.Printf("EmailAddresses: %s \n", cert.EmailAddresses) fmt.Printf("IP Address: %s \n", cert.IPAddresses) fmt.Printf("DNSNames: %s \n", cert.DNSNames) fmt.Printf("SerialNumber: %x \n", cert.SerialNumber) fmt.Printf("SubjectKeyId: %x \n", cert.SubjectKeyId) fmt.Printf("AuthorityKeyId: %x \n", cert.AuthorityKeyId) }
./edgetk -pkey text -cert certificate.pem echo $?
O processo típico para configurar um cliente externo para autenticação usando um certificado é o seguinte:
1) o cliente gera um par de chaves assimétricas (chaves pública e privada);
2) o cliente gera um pedido de assinatura de certificado para a chave pública e o envia para o servidor;
3) o servidor assina a chave pública e devolve esta assinatura (o "certificado") ao cliente;
4) o cliente armazena a chave privada junto com este certificado em formato pfx. Agora, quando o cliente se conecta ao servidor, o certificado é apresentado e o cliente é autenticado.
Salvar certificado e chave privada em formato PFX.
./edgetk -pkey pkcs12 -key Private.pem -cert CERTIFICATE.crt
Analisar certificado PFX.
./edgetk -pkey pkcs12 -cert CERTIFICATE.pfx
A função Diffie-Hellman é um protocolo de troca de chaves criptográficas utilizado para estabelecer uma chave compartilhada entre duas partes que desejam se comunicar de forma segura por meio de um canal não seguro. Esse protocolo foi desenvolvido por Whitfield Diffie e Martin Hellman em 1976 e é um dos algoritmos mais utilizados para a criptografia de chaves públicas.
O protocolo Diffie-Hellman funciona da seguinte forma: cada parte gera um par de chaves assimétricas (uma chave pública e uma chave privada) e troca as chaves públicas. Em seguida, as partes usam a chave privada e a chave pública do outro para gerar um segredo compartilhado, que pode ser usado para criptografar e descriptografar mensagens.
ECDH (Elliptic Curve Diffie-Hellman) é uma variação da função Diffie-Hellman que utiliza criptografia de curva elíptica para realizar o compartilhamento de segredos. Neste caso usaremos a curva 25519, que é uma função de derivação de segredo compartilhado baseado em curva elíptica com estrutura Montgomery (by²=x³+ax²+x):
GolangAlice Bob ----- --- choose private key: choose private key: d_A d_B | | v v compute public key: compute public key: Q_A = d_A * BasePoint_Mont Q_B = d_B * BasePoint_Mont | | v v ----- Begin Key Exchange Phase ----- | | v v compute shared secret: compute shared secret: S_A = Montgomery(Q_B * d_A) S_B = Montgomery(Q_A * d_B) | | v v ----- End Key Exchange Phase ----- | | v v (S_A) (S_B)
Linha de Comandopackage main import ( "crypto/rand" "encoding/hex" "fmt" "golang.org/x/crypto/curve25519" ) func main() { // Generate private key and public key pair (Alice) var alicePrivate, alicePublic [32]byte rand.Read(alicePrivate[:]) curve25519.ScalarBaseMult(&alicePublic, &alicePrivate) // Generate private key and public key pair (Bob) var bobPrivate, bobPublic [32]byte rand.Read(bobPrivate[:]) curve25519.ScalarBaseMult(&bobPublic, &bobPrivate) // Compute shared key (Alice) var sharedKeyAlice [32]byte curve25519.ScalarMult(&sharedKeyAlice, &alicePrivate, &bobPublic) // Convert and display shared key as hexadecimal sharedKeyHexAlice := hex.EncodeToString(sharedKeyAlice[:]) fmt.Println("Shared Key (Alice):", sharedKeyHexAlice) // Compute shared key (Bob) var sharedKeyBob [32]byte curve25519.ScalarMult(&sharedKeyBob, &bobPrivate, &alicePublic) // Convert and display shared key as hexadecimal sharedKeyHexBob := hex.EncodeToString(sharedKeyBob[:]) fmt.Println("Shared Key (Bob):", sharedKeyHexBob) }
./edgetk -pkey keygen -algorithm x25519 [-pass "pass"] ./edgetk -pkey x25519 -key private.pem [-pass "pass"] -pub peerkey.pem
É a prática sistemática de codificar uma mensagem para que ela se torne incompreensível, para esconder informações confidenciais. Esse processo é feito por meio de operações aritméticas realizadas por um programa de computador, que criptografa a mensagem com uma chave secreta. Dessa forma, o emissor do documento envia o conteúdo criptografado e, quando ele é recebido por alguém, é preciso que essa pessoa tenha a chave correta para transformá-lo, novamente, em texto legível.
GolangResult Decrypted: <?php $iv = "0000000000000000"; $pass = "1234567890abcdef"; $method = 'aes-128-ctr'; print (openssl_decrypt("VCfJzWnjYrUF9QYL+Kg=", $method, $pass, false, $iv)); ?> Result Encrypted: <?php $iv = "0000000000000000"; $pass = "1234567890abcdef"; $method = 'aes-128-ctr'; print (openssl_encrypt("SECRET MESSAGE", $method, $pass, false, $iv)); ?>
Linha de Comandopackage main import ( "crypto/aes" "crypto/cipher" "encoding/base64" "fmt" ) func main() { // Key and IV must have the same length for AES-128 (16 bytes). key := []byte("1234567890abcdef") iv := []byte("0000000000000000") // Encrypted text encryptedText := "VCfJzWnjYrUF9QYL+Kg=" // Decrypt decryptedText, err := decrypt(key, iv, encryptedText) if err != nil { fmt.Println("Error decrypting:", err) return } fmt.Println("Result Decrypted:", decryptedText) // Text to encrypt textToEncrypt := "SECRET MESSAGE" // Encrypt encryptedResult, err := encrypt(key, iv, textToEncrypt) if err != nil { fmt.Println("Error encrypting:", err) return } fmt.Println("Result Encrypted:", encryptedResult) } // Function to decrypt using AES-128-CTR func decrypt(key, iv []byte, ciphertext string) (string, error) { block, err := aes.NewCipher(key) if err != nil { return "", err } encrypted, err := base64.StdEncoding.DecodeString(ciphertext) if err != nil { return "", err } mode := cipher.NewCTR(block, iv) mode.XORKeyStream(encrypted, encrypted) return string(encrypted), nil } // Function to encrypt using AES-128-CTR func encrypt(key, iv []byte, plaintext string) (string, error) { block, err := aes.NewCipher(key) if err != nil { return "", err } encrypted := make([]byte, len(plaintext)) mode := cipher.NewCTR(block, iv) mode.XORKeyStream(encrypted, []byte(plaintext)) return base64.StdEncoding.EncodeToString(encrypted), nil }
./edgetk -crypt enc -cipher aes -mode ctr -key $key < plaintext.ext > ciphertext.ext ./edgetk -crypt dec -cipher aes -mode ctr -key $key < ciphertext.ext > plaintext.ext
A criptografia autenticada (AE) e a criptografia autenticada com dados associados (AEAD) são formas de criptografia que garantem simultaneamente a confidencialidade e autenticidade dos dados. Fornece criptografia autenticada (confidencialidade e autenticação) e a capacidade de verificar a integridade e autenticação de dados autenticados adicionais (AAD) que são enviados de forma transparente. Compatível com ARIA e AES, em modo CCM e GCM, e Chacha20-Poly1305.
Golang<?php function encrypt($plaintext, $key, $aad = '') { $nonceSize = 12; // GCM standard nonce size $nonce = random_bytes($nonceSize); $ciphertext = openssl_encrypt( $plaintext, 'aes-256-gcm', $key, OPENSSL_RAW_DATA, $nonce, $tag, $aad ); return $nonce . $ciphertext . $tag; } function decrypt($ciphertext, $key, $aad = '') { $nonceSize = 12; // GCM standard nonce size $tagSize = 16; // Assuming a 16-byte tag $nonce = substr($ciphertext, 0, $nonceSize); $tag = substr($ciphertext, -$tagSize); $ciphertext = substr($ciphertext, $nonceSize, -$tagSize); return openssl_decrypt( $ciphertext, 'aes-256-gcm', $key, OPENSSL_RAW_DATA, $nonce, $tag, $aad ); } // Example usage: $keyHex = ''; // Provide your key in hexadecimal format $key = hex2bin($keyHex); $plaintext = "Hello, AES-GCM!"; // Encrypt $ciphertext = encrypt($plaintext, $key); echo "Encrypted: " . bin2hex($ciphertext) . PHP_EOL; // Decrypt $decrypted = decrypt($ciphertext, $key); echo "Decrypted: " . $decrypted . PHP_EOL; ?>
Linha de Comandopackage main import ( "bytes" "crypto/aes" "crypto/cipher" "crypto/rand" "encoding/hex" "flag" "fmt" "io" "log" "os" ) var ( aad = flag.String("a", "", "additional associated data") dec = flag.Bool("d", false, "decrypt instead of encrypt") key = flag.String("k", "", "symmetric key") ) func main() { flag.Parse() var keyHex string keyHex = *key var key []byte var err error if keyHex == "" { key = make([]byte, 256/8) _, err = io.ReadFull(rand.Reader, key) if err != nil { log.Fatal(err) } fmt.Fprintln(os.Stderr, "Key=", hex.EncodeToString(key)) } else { key, err = hex.DecodeString(keyHex) if err != nil { log.Fatal(err) } if len(key) != 256/8 { log.Fatal("Invalid key size.") } } buf := bytes.NewBuffer(nil) var data io.Reader data = os.Stdin io.Copy(buf, data) msg := buf.Bytes() var c cipher.Block c, err = aes.NewCipher(key) if err != nil { log.Fatal(err) } aead, _ := cipher.NewGCMWithTagSize(c, 16) if *dec == false { nonce := make([]byte, aead.NonceSize(), aead.NonceSize()+len(msg)+aead.Overhead()) if _, err := io.ReadFull(rand.Reader, nonce); err != nil { log.Fatal(err) } out := aead.Seal(nonce, nonce, msg, []byte(*aad)) fmt.Printf("%s", out) os.Exit(0) } if *dec == true { nonce, msg := msg[:aead.NonceSize()], msg[aead.NonceSize():] out, err := aead.Open(nil, nonce, msg, []byte(*aad)) if err != nil { log.Fatal(err) } fmt.Printf("%s", out) os.Exit(0) } }
./edgetk -crypt enc -cipher aes -mode gcm -key $key < plaintext.ext > ciphertext.ext ./edgetk -crypt dec -cipher aes -mode gcm -key $key < ciphertext.ext > plaintext.ext
O HMAC (Hash-based Message Authentication Code) é um método de autenticação de mensagem que utiliza uma função hash criptográfica em conjunto com uma chave secreta para produzir um código de autenticação. Ele fornece integridade e autenticidade aos dados, permitindo que uma parte possa verificar se uma mensagem não foi alterada e se originou de uma fonte confiável.
Golang<?php // Message to authenticate $message = "Hello, world!"; // Secret key $key = "my_secret_key"; // Hash algorithm (SHA256, SHA512, etc.) $algorithm = "sha256"; // Calculate the HMAC $hmac = hash_hmac($algorithm, $message, $key); echo "Message: " . $message . "
"; echo "HMAC: " . $hmac . "
"; ?>
Linha de Comandopackage main import ( "crypto/hmac" "crypto/sha256" "fmt" ) func main() { // Message to authenticate message := "Hello, world!" // Secret key key := []byte("my_secret_key") // Calculate the HMAC using SHA-256 as the hash algorithm h := hmac.New(sha256.New, key) h.Write([]byte(message)) hmacBytes := h.Sum(nil) fmt.Println("Message:", message) fmt.Printf("HMAC: %x\n", hmacBytes) }
echo -n "Hello, world!" > FILE ./edgetk -mac hmac -key "my_secret_key" [-md sha256] FILE
A função PBKDF2 (Password-Based Key Derivation Function 2) é um algoritmo criptográfico que transforma uma senha e um salt em uma chave derivada, utilizando um número ajustável de iterações e um algoritmo de hash, como SHA-256. Número de iterações "iter" na função PBKDF2 tem o propósito de aumentar o custo computacional da derivação de chave, tornando-a mais intensiva em recursos. Isso é feito para fortalecer a resistência da chave derivada a ataques de força bruta.
Golang<?php function deriveKey($password, $salt, $iterations) { $keyLength = 256 / 8; // 256 bits key length $key = hash_pbkdf2("sha256", $password, $salt, $iterations, $keyLength, true); return $key; } // Example usage: $password = ''; // Provide your password $salt = ''; // Provide your salt $iterations = 1; $derivedKey = deriveKey($password, $salt, $iterations); echo bin2hex($derivedKey) . PHP_EOL; ?>
Linha de Comandopackage main import ( "crypto/sha256" "flag" "fmt" "golang.org/x/crypto/pbkdf2" ) var ( iter = flag.Int("iter", 1, "iter") key = flag.String("key", "", "password") salt = flag.String("salt", "", "salt") ) func main() { flag.Parse() keyRaw := pbkdf2.Key([]byte(*key), []byte(*salt), *iter, 256/8, sha256.New) fmt.Printf("%x\n", keyRaw) }
./edgetk -kdf pbkdf2 -key "" -salt "" -iter 1 [-md sha256] [-bits 256]
É um algoritmo de derivação de chave que utiliza um código de autenticação de mensagem baseado em hash (HMAC) para derivar chaves criptográficas de um material de chave de origem (IKM), incorporando informações opcionais de salt e contexto e fornecendo uma maneira segura e flexível para gerar chaves de comprimentos especificados para vários aplicativos criptográficos.
Golang<?php function hkdf($algorithm, $key, $salt, $info, $length) { if (empty($key)) { throw new InvalidArgumentException("Key cannot be empty"); } return hash_hkdf($algorithm, $key, $length, $info, $salt); } // Example usage: $masterKey = ''; // Provide your master key $salt = ''; // Provide your salt $info = ''; // Provide additional info $derivedKeyLength = 32; // Output length in bytes try { $derivedKey = hkdf("sha256", $masterKey, $salt, $info, $derivedKeyLength); echo bin2hex($derivedKey) . PHP_EOL; } catch (Exception $e) { echo "Error: " . $e->getMessage() . PHP_EOL; } ?>
Linha de Comandopackage main import ( "crypto/sha256" "flag" "fmt" "golang.org/x/crypto/hkdf" "hash" "io" "log" ) var ( info = flag.String("info", "", "additional info") key = flag.String("key", "", "master key") salt = flag.String("salt", "", "salt") ) func main() { flag.Parse() hash, err := Hkdf([]byte(*key), []byte(*salt), []byte(*info)) if err != nil { log.Fatal(err) } fmt.Printf("%x\n", hash[:256/8]) } func Hkdf(master, salt, info []byte) ([128]byte, error) { var myHash func() hash.Hash myHash = sha256.New hkdf := hkdf.New(myHash, master, salt, info) key := make([]byte, 256/8) _, err := io.ReadFull(hkdf, key) var result [128]byte copy(result[:], key) return result, err }
./edgetk -kdf hkdf -key "" -salt "" -info "AAD" [-md sha256] [-bits 256]
Calcular valor entrópico com a equação de Shannon em Float64.
package main import ( "fmt" "flag" "math" "strings" ) var ( key = flag.String("k", "", "Passphrase/password.") ) func main(){ flag.Parse() fmt.Println(H(*key)) } func H(data string) (entropy float64) { if data == "" { return 0 } for i := 0; i < 256; i++ { px := float64(strings.Count(data, string(byte(i)))) / float64(len(data)) if px > 0 { entropy += -px * math.Log2(px) } } return entropy }
Com a medida de informação H(X) = -Σ [ p(x) * log2(p(x)) ]
, a entropia de Shannon, torna-se possível analisar a capacidade do canal de comunicação e investir em tratamentos de dados, dando origem ao que se chama atualmente de Teoria da Informação.
A entropia em float64 é uma medida da quantidade de incerteza ou desordem em um conjunto de dados representados como números em ponto flutuante (float64). Neste contexto, a função H(data string) (entropy float64)
calcula a entropia de uma string de dados ASCII (caracteres de 0 a 255) usando a fórmula de entropia de Shannon.
A fórmula usada para calcular a entropia de Shannon é:
H(X) = -Σ [ p(x) * log2(p(x)) ]
• H(X)
representa a entropia da variável aleatória X.
• Σ indica a soma sobre todos os valores possíveis de x.
• p(x)
é a probabilidade de ocorrência do valor x.
• log2(p(x))
é o logaritmo na base 2 da probabilidade p(x)
.
1-) Recebe uma string 'data' como entrada.
2-) Inicializa a variável 'entropy' como 0.0. Esta variável será usada para acumular a entropia calculada.
3-) Verifica se a string 'data' está vazia. Se estiver vazia, retorna 0.0, indicando que não há entropia em uma string vazia.
4-) Em um loop de i de 0 a 255, a função calcula a probabilidade 'px' de cada byte (caractere) em relação ao tamanho total da string 'data'. Isso é feito contando quantas vezes cada byte ocorre na string e dividindo pelo comprimento total da string.
5-) Se a probabilidade 'px' for maior que zero (ou seja, o byte ocorreu na string), a função calcula a contribuição desse byte para a entropia usando a fórmula de Shannon: -px * math.Log2(px)
.
6-) Essa contribuição à entropia é acumulada na variável 'entropy' em cada iteração do loop.
7-) Finalmente, a função retorna o valor total acumulado de 'entropy', que é uma medida da entropia da string 'data' em bits.
Este programa é um gerador de senhas de linha de comando implementado em Go que auxilia webmasters e administradores de servidores na criação de senhas aleatórias e seguras, através do SSH do servidor. Ele permite que o usuário gere senhas aleatórias com várias configurações.
As senhas dos documentos PDF serão geradas por este meio, isto é, a senha das partes é derivada de uma `seed`. Essa abordagem adiciona uma camada adicional de segurança, pois as senhas resultantes são únicas, complexas e derivadas de uma fonte de entropia forte. O processo completo será integrado ao código Go, garantindo a segurança na geração e utilização das senhas no contexto da criptografia do documento PDF.
• Geração de senhas aleatórias
• Configuração do tamanho da senha
• Seleção de conjuntos de caracteres (minúsculas, maiúsculas, numéricas, especiais)
• Opção para evitar caracteres ambíguos
• Opção para soletrar as senhas usando um alfabeto fonético
O programa pode ser executado através da linha de comando com as seguintes opções:
-l
: define o tamanho da senha (padrão: 12)
-n
: define o número de senhas a serem geradas (padrão: 6)
-L
: usa caracteres minúsculos
-U
: usa caracteres maiúsculos
-N
: usa caracteres numéricos
-S
: usa caracteres especiais
-H
: evita caracteres ambíguos
-spell
: soletra as senhas usando um alfabeto fonético
-seed
: especifica uma semente para geração de números aleatórios
Linha de Comandopackage main import ( "flag" "fmt" "math/rand" "strings" "time" "unicode" ) const ( lowerChars = "abcdefghijklmnopqrstuvwxyz" upperChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" numericChars = "0123456789" specialChars = "!@#$%&*()-_=+[]{};:,.<>/?" ambiguousChars = "l1IO0" ) var ( useLower bool useUpper bool useNumeric bool useSpecial bool avoidAmbiguous bool spell bool seed string ) func main() { var ( length int numPasswords int ) flag.IntVar(&length, "l", 12, "Password length") flag.IntVar(&numPasswords, "n", 6, "Number of passwords to generate") flag.BoolVar(&useLower, "L", true, "Use lowercase characters") flag.BoolVar(&useUpper, "U", true, "Use uppercase characters") flag.BoolVar(&useNumeric, "N", true, "Use numeric characters") flag.BoolVar(&useSpecial, "S", false, "Use special characters") flag.BoolVar(&avoidAmbiguous, "H", false, "Avoid ambiguous characters") flag.BoolVar(&spell, "spell", false, "Spell passwords using phonetic alphabet") flag.StringVar(&seed, "seed", "", "Specify a seed for random number generation") flag.Parse() if !(useLower || useUpper || useNumeric || useSpecial) { fmt.Println("Please select at least one character set.") return } if seed != "" { seedInt := stringToSeed(seed) rand.Seed(seedInt) } else { rand.Seed(time.Now().UnixNano()) } characters := "" if useLower { characters += lowerChars } if useUpper { characters += upperChars } if useNumeric { characters += numericChars } if useSpecial { characters += specialChars } if avoidAmbiguous { // Remove ambiguous characters only once if avoidAmbiguous is set characters = removeCharacters(characters, ambiguousChars) } for i := 0; i < numPasswords; i++ { password := generatePassword(length, characters) if spell { fmt.Printf("%s ", password) password = spellPassword(password) } fmt.Println(password) } } func stringToSeed(s string) int64 { var seed int64 for _, char := range s { seed += int64(char) } return seed } func generatePassword(length int, charset string) string { password := make([]byte, length) for i := 0; i < length; i++ { randomIndex := rand.Intn(len(charset)) password[i] = charset[randomIndex] } return string(password) } func spellPassword(password string) string { phoneticAlphabet := map[rune]string{ 'a': "alfa", 'A': "Alpha", 'b': "bravo", 'B': "Bravo", 'c': "charlie", 'C': "Charlie", 'd': "delta", 'D': "Delta", 'e': "echo", 'E': "Echo", 'f': "foxtrot", 'F': "Foxtrot", 'g': "golf", 'G': "Golf", 'h': "hotel", 'H': "Hotel", 'i': "india", 'I': "India", 'j': "juliett", 'J': "Juliett", 'k': "kilo", 'K': "Kilo", 'l': "lima", 'L': "Lima", 'm': "mike", 'M': "Mike", 'n': "november", 'N': "November", 'o': "oscar", 'O': "Oscar", 'p': "papa", 'P': "Papa", 'q': "quebec", 'Q': "Quebec", 'r': "romeo", 'R': "Romeo", 's': "sierra", 'S': "Sierra", 't': "tango", 'T': "Tango", 'u': "uniform", 'U': "Uniform", 'v': "victor", 'V': "Victor", 'w': "whiskey", 'W': "Whiskey", 'x': "x-ray", 'X': "X-ray", 'y': "yankee", 'Y': "Yankee", 'z': "zulu", 'Z': "Zulu", '0': "ZERO", '1': "ONE", '2': "TWO", '3': "THREE", '4': "FOUR", '5': "FIVE", '6': "SIX", '7': "SEVEN", '8': "EIGHT", '9': "NINE", '!': "EXCLAMATION", '@': "AT", '#': "HASH", '$': "DOLLAR", '%': "PERCENT", '^': "CARET", '&': "AMPERSAND", '*': "ASTERISK", '(': "LEFT_PARENTHESIS", ')': "RIGHT_PARENTHESIS", '-': "HYPHEN", '_': "UNDERSCORE", '=': "EQUAL", '+': "PLUS", '[': "LEFT_BRACKET", ']': "RIGHT_BRACKET", '{': "LEFT_CURLY_BRACE", '}': "RIGHT_CURLY_BRACE", '|': "PIPE", ';': "SEMICOLON", ':': "COLON", ',': "COMMA", '.': "PERIOD", '<': "LESS_THAN", '>': "GREATER_THAN", '/': "SLASH", '?': "QUESTION_MARK", } splittedPassword := strings.Split(password, "") var spelledPassword []string for i, char := range splittedPassword { charRune := rune(char[0]) spelledChar, found := phoneticAlphabet[charRune] if !found { spelledChar = string(charRune) } if i == 0 && unicode.IsUpper(charRune) { spelledChar = strings.Title(spelledChar) } spelledPassword = append(spelledPassword, spelledChar) } return strings.Join(spelledPassword, "-") } func removeCharacters(set string, charsToRemove string) string { return strings.Map(func(r rune) rune { if strings.ContainsRune(charsToRemove, r) { return -1 } return r }, set) }
SintaxeUsage of apg: -H Avoid ambiguous characters -L Use lowercase characters (default true) -N Use numeric characters (default true) -S Use special characters -U Use uppercase characters (default true) -l int Password length (default 12) -n int Number of passwords to generate (default 6) -seed string Specify a seed for random number generation -spell Spell passwords using phonetic alphabet
Saída./apg -L -N -U -spell
vwItH3bGEEFZ victor-whiskey-India-tango-Hotel-THREE-bravo-Golf-Echo-Echo-Foxtrot-Zulu xOGfGFkHL20e x-ray-Oscar-Golf-foxtrot-Golf-Foxtrot-kilo-Hotel-Lima-TWO-ZERO-echo e5KLYOK6mA1m echo-FIVE-Kilo-Lima-Yankee-Oscar-Kilo-SIX-mike-Alpha-ONE-mike DLBAm5HgPofk Delta-Lima-Bravo-Alpha-mike-FIVE-Hotel-golf-Papa-oscar-foxtrot-kilo 738e3h7k2ZQ3 SEVEN-THREE-EIGHT-echo-THREE-hotel-SEVEN-kilo-TWO-Zulu-Quebec-THREE aQ2TdulqJ780 alfa-Quebec-TWO-Tango-delta-uniform-lima-quebec-Juliett-SEVEN-EIGHT-ZERO
1.1. Certificado Digital: documento eletrônico que atesta a identidade de uma pessoa, empresa ou órgão público em meio eletrônico.
1.2. Algoritmo de Chave Pública: sistema criptográfico assimétrico que utiliza uma chave pública para criptografar informações e uma chave privada para descriptografá-las.
1.3. Sistema Único Integrado de Tramitação Eletrônica: sistema que permite a realização de processos e procedimentos administrativos em meio eletrônico, com a utilização de algoritmo de chave pública e certificados digitais.
2.1. Ao utilizar o Sistema Único Integrado de Tramitação Eletrônica, o usuário declara ter lido, compreendido e concordado com os presentes Termos de Uso.
3.1. A utilização do Sistema Único Integrado de Tramitação Eletrônica está disponível apenas para pessoas físicas e jurídicas certificadas, órgãos públicos e profissionais que possuam certificados digitais válidos.
3.2. É de responsabilidade do usuário garantir a segurança e sigilo das informações e senhas de acesso ao Sistema.
3.3. O usuário é responsável por manter atualizadas as informações pessoais e de contato informadas no momento do cadastro no Sistema.
4.1. Todos os direitos de propriedade intelectual sobre o Sistema Único Integrado de Tramitação Eletrônica pertencem ao proprietário do sistema Pedro F. Albanese. Vide Lei 9.610/98, Art. 7º, inciso XII.
4.2. É vedada a reprodução, distribuição ou utilização não autorizada do Sistema ou de seus conteúdos por terceiros.
5.1. O proprietário do Sistema Único Integrado de Tramitação Eletrônica não se responsabiliza por quaisquer danos diretos ou indiretos decorrentes do uso do Sistema, incluindo, mas não se limitando a perda de dados, interrupção do serviço, ou danos causados por terceiros.
6.1. Os presentes Termos de Uso podem ser atualizados ou modificados a qualquer momento, sem aviso prévio.
6.2. A legislação brasileira será aplicável a quaisquer disputas decorrentes do uso do Sistema Único Integrado de Tramitação Eletrônica.
6.3. Em caso de dúvidas ou sugestões sobre os presentes Termos de Uso, o usuário pode entrar em contato com o proprietário do sistema por meio do canal de suporte disponibilizado no Sistema.
6.4. O usuário reconhece que o proprietário do sistema poderá realizar manutenções, atualizações e ajustes no Sistema, a fim de garantir o seu correto funcionamento e melhorias na qualidade dos serviços prestados, sem que isso gere qualquer tipo de prejuízo ou direito de indenização ao usuário.
6.5. O usuário é responsável pela segurança de seu certificado digital e deve tomar todas as medidas necessárias para garantir sua integridade e confidencialidade, incluindo, mas não se limitando a, manter seu certificado em local seguro, não compartilhar sua senha de acesso e não utilizar computadores públicos ou de terceiros para acessar o Sistema.
6.6. O usuário declara e garante que não utilizará o Sistema para fins ilícitos, fraudulentos, abusivos, difamatórios, ofensivos, discriminatórios ou quaisquer outros que violem a legislação em vigor, bem como os presentes Termos de Uso.
6.7. O proprietário do sistema não se responsabiliza por quaisquer danos, prejuízos ou perdas decorrentes do uso indevido, inadequado ou irregular do Sistema pelo usuário, ou por terceiros autorizados pelo usuário, inclusive em caso de perda, extravio ou uso indevido do certificado digital.
6.8. O proprietário do sistema poderá suspender ou cancelar o acesso do usuário ao Sistema, a qualquer momento e sem necessidade de prévio aviso, em caso de descumprimento dos presentes Termos de Uso ou em razão de quaisquer outras circunstâncias que justifiquem a medida.
6.9. Os presentes Termos de Uso poderão ser alterados, a critério do proprietário do sistema, a qualquer momento e sem necessidade de prévio aviso ao usuário. O usuário deve manter-se atualizado em relação aos Termos de Uso vigentes, que estarão sempre disponíveis para consulta no Sistema.
6.10. Qualquer controvérsia decorrente dos presentes Termos de Uso ou do uso do Sistema será resolvida de acordo com as leis em vigor no Brasil, sendo o foro da Comarca de São Paulo-SP o competente para dirimir quaisquer dúvidas ou conflitos.
Copyright (c) 2018 Pedro F. Albanese <pedroalbanese@hotmail.com>
Permission to use, copy, modify, and distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.