O Python tem uma maneira simples e integrada de codificar / decodificar strings usando uma senha?
Algo assim:
>>> encode('John Doe', password = 'mypass')
'sjkl28cn2sx0'
>>> decode('sjkl28cn2sx0', password = 'mypass')
'John Doe'
Portanto, a string "John Doe" é criptografada como 'sjkl28cn2sx0'. Para obter a string original, eu "desbloquearia" essa string com a chave 'mypass', que é uma senha no meu código-fonte. Gostaria que essa fosse a maneira como posso criptografar / descriptografar um documento do Word com uma senha.
Eu gostaria de usar essas strings criptografadas como parâmetros de URL. Meu objetivo é ofuscação, não forte segurança; nada de missão crítica está sendo codificado. Sei que poderia usar uma tabela de banco de dados para armazenar chaves e valores, mas estou tentando ser minimalista.
python
encryption
passwords
RexE
fonte
fonte
Respostas:
Supondo que você esteja procurando apenas uma ofuscação simples que irá obscurecer as coisas do observador muito casual, e você não está procurando usar bibliotecas de terceiros. Eu recomendaria algo como a cifra de Vigenere. É uma das mais fortes cifras antigas simples.
Cifra de Vigenère
É rápido e fácil de implementar. Algo como:
Decodificar é praticamente o mesmo, exceto que você subtrai a chave.
É muito mais difícil quebrar se as strings que você está codificando forem curtas e / ou se for difícil adivinhar o comprimento da frase-senha usada.
Se você está procurando por algo criptográfico, PyCrypto é provavelmente sua melhor aposta, embora as respostas anteriores negligenciem alguns detalhes: O modo ECB no PyCrypto requer que sua mensagem seja um múltiplo de 16 caracteres. Então, você deve preencher. Além disso, se você quiser usá-los como parâmetros de URL, use
base64.urlsafe_b64_encode()
, em vez do padrão. Isso substitui alguns dos caracteres no alfabeto base64 por caracteres seguros para URL (como o nome sugere).No entanto, você deve estar ABSOLUTAMENTE certo de que essa camada muito fina de ofuscação é suficiente para suas necessidades antes de usá-lo. O artigo da Wikipedia ao qual vinculei fornece instruções detalhadas para quebrar a cifra, de modo que qualquer pessoa com uma quantidade moderada de determinação poderia quebrá-la facilmente.
fonte
'str' object cannot be interpreted as an integer
Como você afirma explicitamente que deseja obscuridade e não segurança, evitaremos repreendê-lo pela fraqueza do que você sugere :)
Então, usando PyCrypto:
Se alguém conseguir seu banco de dados e sua base de código, será capaz de decodificar os dados criptografados. Mantenha seu
secret_key
seguro!fonte
encrypt
função em particular é dlitz.net/software/pycrypto/api/current/… então você não deve tentar reutilizá-la.Python não tem esquemas de criptografia embutidos, não. Você também deve levar a sério o armazenamento de dados criptografados; esquemas de criptografia triviais que um desenvolvedor entende como inseguros e um esquema de brinquedo pode muito bem ser confundido com um esquema seguro por um desenvolvedor menos experiente. Se você criptografar, criptografe corretamente.
No entanto, você não precisa fazer muito trabalho para implementar um esquema de criptografia adequado. Em primeiro lugar, não reinvente a roda da criptografia , use uma biblioteca de criptografia confiável para lidar com isso para você. Para Python 3, essa biblioteca confiável é
cryptography
.Eu também recomendo que a criptografia e descriptografia se apliquem a bytes ; codifique as mensagens de texto em bytes primeiro;
stringvalue.encode()
codifica para UTF8, facilmente revertido novamente usandobytesvalue.decode()
.Por último, mas não menos importante, ao criptografar e descriptografar, falamos sobre chaves , não senhas. Uma chave não deve ser memorável por humanos, é algo que você armazena em um local secreto, mas legível por máquina, ao passo que uma senha geralmente pode ser lida e memorizada por humanos. Você pode derivar uma chave de uma senha, com um pouco de cuidado.
Mas para um aplicativo da web ou processo em execução em um cluster sem atenção humana para mantê-lo em execução, você deseja usar uma chave. As senhas são para quando apenas um usuário final precisa de acesso às informações específicas. Mesmo assim, você geralmente protege o aplicativo com uma senha e, em seguida, troca informações criptografadas usando uma chave, talvez uma anexada à conta do usuário.
Criptografia de chave simétrica
Fernet - AES CBC + HMAC, fortemente recomendado
A
cryptography
biblioteca inclui a receita Fernet , uma receita de práticas recomendadas para usar criptografia. Fernet é um padrão aberto , com implementações prontas em uma ampla gama de linguagens de programação e pacotes de criptografia AES CBC para você com informações de versão, um carimbo de data / hora e uma assinatura HMAC para evitar adulteração de mensagens.Fernet torna muito fácil criptografar e descriptografar mensagens e mantê-lo seguro. É o método ideal para criptografar dados com um segredo.
Eu recomendo que você use
Fernet.generate_key()
para gerar uma chave segura. Você também pode usar uma senha (próxima seção), mas uma chave secreta completa de 32 bytes (16 bytes para criptografar, mais outros 16 para a assinatura) será mais segura do que a maioria das senhas que você possa imaginar.A chave que o Fernet gera é um
bytes
objeto com URL e caracteres de base64 de arquivo seguro, portanto, imprimível:Para criptografar ou descriptografar mensagens, crie uma
Fernet()
instância com a chave fornecida e chameFernet.encrypt()
ouFernet.decrypt()
, a mensagem de texto simples a ser criptografada e o token criptografado sãobytes
objetos.encrypt()
e asdecrypt()
funções seriam semelhantes a:Demo:
Fernet com senha - chave derivada de senha, enfraquece um pouco a segurança
Você pode usar uma senha em vez de uma chave secreta, desde que use um método de derivação de chave forte . Em seguida, você deve incluir o salt e a contagem de iteração HMAC na mensagem, para que o valor criptografado não seja mais compatível com Fernet sem primeiro separar salt, count e token Fernet:
Demo:
Incluir o salt na saída torna possível usar um valor salt aleatório, o que, por sua vez, garante que a saída criptografada seja totalmente aleatória, independentemente da reutilização da senha ou da repetição da mensagem. Incluir a contagem de iterações garante que você possa ajustar os aumentos de desempenho da CPU com o tempo, sem perder a capacidade de descriptografar mensagens mais antigas.
Uma senha sozinha pode ser tão segura quanto uma chave aleatória Fernet de 32 bytes, desde que você gere uma senha aleatória apropriada de um pool de tamanho semelhante. 32 bytes fornece 256 ^ 32 números de chaves, portanto, se você usar um alfabeto de 74 caracteres (26 superior, 26 inferior, 10 dígitos e 12 símbolos possíveis), sua senha deve ter pelo menos
math.ceil(math.log(256 ** 32, 74))
== 42 caracteres. No entanto, um número maior e bem selecionado de iterações HMAC pode mitigar um pouco a falta de entropia, pois isso torna muito mais caro para um invasor entrar com força bruta.Saiba que escolher uma senha mais curta, mas ainda razoavelmente segura, não prejudicará esse esquema, apenas reduzirá o número de valores possíveis que um invasor de força bruta teria que pesquisar; certifique-se de escolher uma senha forte o suficiente para seus requisitos de segurança .
Alternativas
Obscurecedor
Uma alternativa é não criptografar . Não fique tentado a usar apenas uma cifra de baixa segurança ou uma implementação caseira do, digamos Vignere. Não há segurança nessas abordagens, mas podem dar a um desenvolvedor inexperiente que recebe a tarefa de manter seu código no futuro a ilusão de segurança, que é pior do que nenhuma segurança.
Se tudo o que você precisa é obscuridade, apenas base64 os dados; para requisitos seguros de URL, a
base64.urlsafe_b64encode()
função é adequada. Não use uma senha aqui, apenas codifique e pronto. No máximo, adicione alguma compressão (comozlib
):Isso se transforma
b'Hello world!'
emb'eNrzSM3JyVcozy_KSVEEAB0JBF4='
.Integridade apenas
Se tudo o que você precisa é uma maneira de se certificar de que os dados podem ser confiáveis e inalterados após terem sido enviados a um cliente não confiável e recebidos de volta, então você deseja assinar os dados, você pode usar a
hmac
biblioteca para isso com SHA1 (ainda considerado seguro para assinatura HMAC ) ou melhor:Use-o para assinar dados e, em seguida, anexe a assinatura aos dados e envie-a ao cliente. Ao receber os dados de volta, divida os dados e a assinatura e verifique. Eu defini o algoritmo padrão para SHA256, então você precisará de uma chave de 32 bytes:
Você pode querer dar uma olhada na
itsdangerous
biblioteca , que empacota tudo isso com serialização e desserialização em vários formatos.Usando criptografia AES-GCM para fornecer criptografia e integridade
Fernet baseia-se no AEC-CBC com uma assinatura HMAC para garantir a integridade dos dados criptografados; um invasor mal-intencionado não pode alimentar seu sistema com dados absurdos para manter seu serviço ocupado em execução em círculos com entrada incorreta, porque o texto cifrado está assinado.
A cifra de bloco do modo Galois / Contador produz texto cifrado e uma etiqueta para servir ao mesmo propósito, portanto, pode ser usada para os mesmos fins. A desvantagem é que, ao contrário do Fernet, não existe uma receita única e fácil de usar para reutilizar em outras plataformas. O AES-GCM também não usa preenchimento, portanto, esse texto cifrado de criptografia corresponde ao comprimento da mensagem de entrada (enquanto o Fernet / AES-CBC criptografa as mensagens em blocos de comprimento fixo, obscurecendo um pouco o comprimento da mensagem).
AES256-GCM usa o segredo usual de 32 bytes como uma chave:
então use
Incluí um carimbo de data / hora para oferecer suporte aos mesmos casos de uso de tempo de vida que o Fernet oferece.
Outras abordagens nesta página, em Python 3
AES CFB - como CBC, mas sem a necessidade de preenchimento
Esta é a abordagem que All Іѕ Vаиітy segue, embora incorretamente. Esta é a
cryptography
versão, mas observe que incluo o IV no texto cifrado , ele não deve ser armazenado como um global (reutilizar um IV enfraquece a segurança da chave e armazená-lo como um módulo global significa que ele será regenerado a próxima invocação do Python, tornando todo o texto cifrado indecifrável):Isso não tem a proteção adicional de uma assinatura HMAC e não há carimbo de data / hora; você mesmo teria que adicioná-los.
O texto acima também ilustra como é fácil combinar blocos de construção básicos de criptografia incorretamente; O manuseio incorreto do valor IV de All Іѕ Vаиітy pode levar a uma violação de dados ou a ilegibilidade de todas as mensagens criptografadas porque o IV foi perdido. Em vez disso, usar o Fernet protege você de tais erros.
AES ECB - não seguro
Se você implementou a criptografia AES ECB anteriormente e ainda precisa suportá-la no Python 3, você ainda pode fazer isso com
cryptography
também. As mesmas ressalvas se aplicam, o ECB não é seguro o suficiente para aplicativos da vida real . Reimplementando essa resposta para Python 3, adicionando tratamento automático de preenchimento:Novamente, falta a assinatura HMAC e você não deve usar o ECB de qualquer maneira. O texto acima existe apenas para ilustrar que
cryptography
pode lidar com os blocos de construção criptográficos comuns, mesmo aqueles que você não deveria realmente usar.fonte
O "encoded_c" mencionado na resposta da cifra Vigenere de @smehmood deve ser "key_c".
Aqui estão as funções de codificação / decodificação de trabalho.
Isenção de responsabilidade: conforme implícito nos comentários, isso não deve ser usado para proteger dados em um aplicativo real, a menos que você leia isto e não se importe em falar com advogados:
O que há de errado com a criptografia XOR?
fonte
encodedmsg = encode('mypassword', 'this is the message éçàèç"')
print encodedmsg
print decode('mypassword', encodedmsg)
funciona bem.Aqui está uma versão Python 3 das funções de 's @qneill resposta :
A codificação / decodificação extras são necessárias porque o Python 3 dividiu strings / matrizes de bytes em dois conceitos diferentes e atualizou suas APIs para refletir isso.
fonte
.encode()).decode()
. no retorno deencode()
e.decode()
na segunda linha emdecode()
.Isenção de responsabilidade: conforme mencionado nos comentários, isso não deve ser usado para proteger dados em um aplicativo real.
O que há de errado com a criptografia XOR?
/crypto/56281/breaking-a-xor-cipher-of-known-key-length
https://github.com/hellman/xortool
Como foi mencionado, a biblioteca PyCrypto contém um conjunto de cifras. A "cifra" XOR pode ser usada para fazer o trabalho sujo se você não quiser fazer isso sozinho:
A cifra funciona da seguinte maneira, sem ter que preencher o texto simples:
Crédito para https://stackoverflow.com/a/2490376/241294 pelas funções de codificação / decodificação de base64 (sou um novato em Python).
fonte
sudo pip3 install pycrypto
.Aqui está uma implementação de criptografia e descriptografia segura de URL usando AES (PyCrypto) e base64.
Se você enfrentar algum problema como este https://bugs.python.org/issue4329 (
TypeError: character mapping must return integer, None or unicode
), usestr(cipher)
durante a decodificação da seguinte forma:Teste:
fonte
TypeError: Object type <class 'str'> cannot be passed to C code
.b'...'
, editei a resposta para referência futura!Trabalhar funções de codificação / decodificação em python3 (adaptado muito pouco da resposta de qneill):
fonte
Obrigado por algumas ótimas respostas. Nada original a acrescentar, mas aqui estão algumas reescritas progressivas da resposta de qneill usando alguns recursos úteis do Python. Espero que você concorde que eles simplificam e esclarecem o código.
fonte
Se você quiser estar seguro, pode usar o Fernet, que é criptograficamente correto. Você pode usar um "salt" estático se não quiser armazená-lo separadamente - você só perderá o dicionário e a prevenção de ataques de arco-íris. Escolhi porque posso escolher senhas longas ou curtas´, o que não é tão fácil com AES.
Se isso for muito complicado, alguém sugeriu criptografar simples
fonte
Quem quer que tenha vindo aqui (e o bountier) parecia estar procurando por uma linha sem muita configuração, que outras respostas não fornecem. Portanto, estou apresentando base64.
Agora, lembre-se de que isso é apenas ofuscação básica e está em ** NENHUM CAMINHO OK PARA A SEGURANÇA ** , mas aqui estão algumas frases simples :
Algumas coisas a serem observadas:
bytes()
ebytes::decode()
=
caracteres. Pessoas como eu absolutamente os decodificam no console javascript quando os vemos em sites. É tão fácil quantobtoa(string)
(js)Agora, se o que você queria nem precisava de uma chave de qualquer tipo, mas apenas um pouco de ofuscação, você pode mais uma vez apenas usar base64, sem nenhum tipo de chave:
fonte
Fernet(key).encrypt(message)
é apenas uma expressão como sua chamada de base64.key
completamente. Cargas de desenvolvedores estão indo para copiar e colar de estouro de pilha sem prestar atenção e vai assumir a chave para ser secreta. Se você deve incluí-lo, pelo menos não o use e avise ou gere uma exceção se usado de qualquer maneira. Não subestime a tolice da cultura de copiar e colar e suas responsabilidades de fornecer funções saudáveis.Vou dar 4 soluções:
1) Usando criptografia Fernet com
cryptography
bibliotecaAqui está uma solução usando o pacote
cryptography
, que você pode instalar normalmente compip install cryptography
:Você pode adaptar com seu próprio salt, contagem de iteração, etc. Este código não está muito longe da resposta de @HCLivess, mas o objetivo é ter funções
encrypt
e prontas para usodecrypt
. Fonte: https://cryptography.io/en/latest/fernet/#using-passwords-with-fernet .Nota: use
.encode()
e.decode()
todo lugar se quiser strings em'John Doe'
vez de bytes comob'John Doe'
.2) Criptografia AES simples com
Crypto
bibliotecaIsso funciona com Python 3:
Observação: você pode remover
base64.b64encode
e.b64decode
se não quiser saída legível em texto e / ou se quiser salvar o texto cifrado no disco como um arquivo binário de qualquer maneira.3) AES usando uma função de derivação de chave de senha melhor e a capacidade de testar se "senha errada inserida", com
Crypto
bibliotecaA solução 2) com AES "modo CFB" está ok, mas tem duas desvantagens: o fato de que
SHA256(password)
pode ser facilmente forçado com uma tabela de consulta e que não há como testar se uma senha errada foi inserida. Isso é resolvido aqui pelo uso de AES no "modo GCM", conforme discutido em AES: como detectar que uma senha incorreta foi inserida? e Este método diz “A senha que você digitou está errada” é seguro? :4) Usando RC4 (nenhuma biblioteca necessária)
Adaptado de https://github.com/bozhu/RC4-Python/blob/master/rc4.py .
(Desatualizado desde as últimas edições, mas mantido para referência futura): Tive problemas ao usar Windows + Python 3.6 + todas as respostas envolvendo
pycrypto
(não consigopip install pycrypto
no Windows) oupycryptodome
(as respostas aqui comfrom Crypto.Cipher import XOR
falhou porqueXOR
não é suportado por estepycrypto
fork; e as soluções usando... AES
também falharam comTypeError: Object type <class 'str'> cannot be passed to C code
). Além disso, a bibliotecasimple-crypt
tem umapycrypto
dependência, portanto não é uma opção.fonte
password_encrypt()
.Isso funciona, mas o comprimento da senha deve ser exatamente igual
8
. Isso é simples e requer pyDes .RESULTADO:
fonte
Uma outra implementação do código @qneill que inclui a soma de verificação CRC da mensagem original, ela lança uma exceção se a verificação falhar:
fonte
Você pode usar AES para criptografar sua string com uma senha. Porém, você vai querer escolher uma senha forte o suficiente para que as pessoas não consigam adivinhá-la facilmente (desculpe, não posso evitar. Sou um aspirante a gênio da segurança).
O AES é forte com um bom tamanho de chave, mas também é fácil de usar com o PyCrypto.
fonte
Bibliotecas externas fornecem algoritmos de criptografia de chave secreta.
Por exemplo, o
Cypher
módulo em PyCrypto oferece uma seleção de muitos algoritmos de criptografia:Crypto.Cipher.AES
Crypto.Cipher.ARC2
Crypto.Cipher.ARC4
Crypto.Cipher.Blowfish
Crypto.Cipher.CAST
Crypto.Cipher.DES
Crypto.Cipher.DES3
Crypto.Cipher.IDEA
Crypto.Cipher.RC5
Crypto.Cipher.XOR
MeTooCrypto é um
Python
wrapper para OpenSSL e fornece (entre outras funções) uma biblioteca de criptografia de propósito geral de força total. Estão incluídas cifras simétricas (como AES).fonte
se você deseja criptografia segura:
para python 2, você deve usar keyczar http://www.keyczar.org/
para python 3, até que o keyczar esteja disponível, escrevi simple-crypt http://pypi.python.org/pypi/simple-crypt
ambos usarão reforço de chave, o que os torna mais seguros do que a maioria das outras respostas aqui. e como eles são tão fáceis de usar, você pode querer usá-los mesmo quando a segurança não for crítica ...
fonte
Portanto, como nada de missão crítica está sendo codificado , você apenas deseja criptografar para ofuscação .
Deixe-me apresentar a cifra do céser
Cifra de César ou mudança de César, é uma das técnicas de criptografia mais simples e conhecidas. É um tipo de cifra de substituição em que cada letra do texto simples é substituída por uma letra com um número fixo de posições abaixo do alfabeto. Por exemplo, com um deslocamento à esquerda de 3, D seria substituído por A, E se tornaria B e assim por diante.
Código de amostra para sua referência:
Vantagens: atende às suas necessidades e é simples e faz toda a codificação.
Desvantagem: pode ser quebrada por algoritmos de força bruta simples (altamente improvável que alguém tentasse passar por todos os resultados extras).
fonte
Adicionar mais um código com decodificar e codificar para referência
fonte