Pergunta

Eu estou olhando para desenvolver um sistema em que eu preciso atribuir a cada utilizador um código pin único para segurança. O usuário só vai introduzir este código pin como um meio de identificar-se. Assim eu não quero que o usuário seja capaz de adivinhar outro código PIN usuários. Assumindo que os usuários max i terá é 100000, quanto tempo deve este código pin ser?

por exemplo. 1234 4532 3423

i deve gerar este código via algum tipo de algoritmo? Ou devo aleatoriamente gerá-lo?

Basicamente, eu não quero que as pessoas sejam capazes de adivinhar outros povos código PIN e deve apoiar um número suficiente de usuários.

Lamento se minha pergunta soa um pouco confuso, mas de bom grado esclarecer quaisquer dúvidas.

muito obrigado.

Atualizar

Depois de ler todas as mensagens abaixo, eu gostaria de acrescentar mais alguns detalhes.

  1. O que eu estou tentando alcançar é algo muito semelhante a um cartão de raspadinha.
  2. Um usuário recebe um cartão, que ele / ela deve arranhar a encontrar o código pin.
  3. Agora, usando este código pin o usuário deve ser capaz de acessar meu sistema.

Não consigo adicionar segurança extra (por exemplo, nome de usuário e senha), como então ele irá impedir o usuário de usar o cartão de zero. Eu quero torná-lo o mais difícil possível para adivinhar o código PIN dentro das limitações.

thankyou a todos por suas respostas surpreendentes novamente.

Foi útil?

Solução

Se assumirmos máximo 100.000 usuários, em seguida, eles podem ter PINs exclusivos com 0-99,999 ie. 5 dígitos.

No entanto, isso tornaria mais fácil de adivinhar os pinos com o número máximo de usuários. Se você pode restringir o número de tentativas por PIN, então você pode ter um PIN mais curto. por exemplo. máximo de 10 tentativas falhadas por IP por dia.

Depende também o valor do que você está protegendo e como catastrófica seria se um estranho fez sair.

Eu iria para 9 dígitos se você quiser mantê-lo curto ou 12 dígitos se você quiser um pouco mais de segurança a partir automatizado adivinhando.

Para gerar os PINs, eu levaria um alta resolução versão do tempo, juntamente com alguns sal e talvez um número pseudo-aleatório, gerar um de hash e usar os primeiros 9 ou 12 dígitos. Verifique se há um atraso razoável e aleatório entre as novas gerações PIN para não gerá-los em um loop , e se possível fazê-los iniciado pelo usuário.

por exemplo. Esquerda (SHA1 (DateTime + sal + pseudo-aleatórios), 9)

Outras dicas

4 dígitos aleatórios deve ser suficiente se você acrescentar que a ID de usuário conhecido único (ainda pode ser o número) [como recomendado pelo starblue]

Pseudo gerador de números aleatórios também deve ser fino. Você pode armazenar estes no DB usando criptografia reversível (AES) ou one-way hash

A principal preocupação que você tem é quantas vezes uma pessoa pode incorretamente a entrada do pino antes de serem bloqueados. Este deve ser baixo, dizem que cerca de três ... Isso vai impedir que as pessoas adivinhando números de outras pessoas.

Qualquer mais de 6 dígitos e as pessoas vão ser esquecê-los, ou pior, escrevê-los em um post-it em seu monitor.

Assumindo uma conta fechaduras com 3 tentativas incorrectas, em seguida, com um pino de 4 dígitos mais um ID de utilizador ID componente (999999) + Pino (1234) dá-lhe uma possibilidade de alguém supondo 3/10000. Será isto aceitável? Se não tornar o comprimento de 5 pinos e obter 3/100000

Posso sugerir uma abordagem alternativa? Dê uma olhada na Perfeito senhas de papel e do derivados que solicitado.

Você pode usar este "tal como está" para gerar PINs de uma só vez, ou simplesmente para gerar um único PIN por usuário.

Tenha em mente, também, que PINs duplicados não são em si um problema: qualquer ataque seria então simplesmente tem que tentar várias ids de usuário

.

(aviso de quilometragem: Definitivamente eu não sou um especialista em segurança.)


Aqui está uma segunda resposta: a partir de re-leitura, eu suponho que você não quer que um usuário-id como tal - você está apenas validar um conjunto de raspadinhas emitidos. Eu também supor que você não quer usar PINs alfabéticos.

Você precisa escolher um comprimento PIN tais que a probabilidade de adivinhar um PIN válido é inferior a 1 / (O número de tentativas você pode proteger contra). Assim, por exemplo, se você tem 1 milhão de PINs válidos, e você quer proteger contra 10000 palpites, você precisará de um PIN de 10 dígitos.

Se você usar de John Graham-Cumming das senhas de papel perfeitos sistema, você pode:

  1. Configure isso para (digamos) de 10 dígitos decimal pinos
  2. Escolha um IV / frase chave secreta
  3. Gerar (digamos) o primeiro milhão de senhas (/ PINs)

Eu suspeito que este é um procedimento genérico que poderia, por exemplo, ser usado para gerar ids produtos 25 alfanuméricos, também.

Desculpe por fazê-lo por aproximação sucessiva; Espero que vem um pouco mais próximo ao que você está procurando.

Muitos dos grandes respostas até agora: simples, eficaz e elegante

Eu estou supondo que a aplicação é um pouco de loteria-like, em que cada usuário recebe uma raspadinha e usa-lo para pedir a sua candidatura se "ele já ganhou!" Assim, a partir dessa perspectiva, algumas novas questões vêm à mente:

Guerra-discar , ou seu equivalente Internet: Pode um usuário desonesto atingiu seu aplicativo repetidamente, dizem adivinhando cada número de 10 dígitos em sucessão? Se isso é uma possibilidade, considerar limitar o número de tentativas de um local particular. Uma maneira eficaz pode ser simplesmente recusar-se a responder a mais do que, digamos, uma tentativa a cada 5 segundos a partir do mesmo endereço IP. Isso faz com que os ataques-driven máquina ineficiente e evita o problema de bloqueio .

problema Lockout : Se você bloquear uma conta permanentemente após qualquer número de tentativas falhadas, você está propenso a ataques de negação de serviço . O atacante acima poderia efetivamente bloquear cada usuário a menos que você reativar as contas depois de um período de tempo. Mas este é um problema somente se seus PINs consistem de uma concatenação óbvia de Usuário ID + Key, porque um invasor poderia tentar cada chave para um determinado ID de usuário. Essa técnica também reduz o espaço da chave drasticamente porque apenas alguns dos dígitos de PIN são verdadeiramente aleatório. Por outro lado, se o PIN é simplesmente uma seqüência de dígitos aleatórios, necessidade de bloqueio só pode ser aplicada ao endereço IP de origem. (Se uma tentativa falhar, nenhuma conta válida é afetada, então o que você faria "bloqueio"?)

O armazenamento de dados : se você realmente está construindo algum tipo de loteria-like sistema que você só precisa armazenar os PINs vencedoras ! Quando um usuário entra em um PIN, você pode procurar uma relativamente pequena lista de pinos / prémios (ou seu equivalente). Você pode tratar "perder" e PINs inválidos identicamente com um "Desculpe, melhor sorte da próxima vez" mensagem ou um prêmio "default" se a economia está certo.

Boa sorte!

A pergunta deveria ser: "quantos palpites são necessárias, em média, para encontrar um código PIN válido, em comparação com quantos palpites atacantes estão fazendo?"

Se você gerar 100 códigos 000 5 dígitos, então, obviamente, leva um palpite. Esta é pouco provável que seja bom o suficiente.

Se você gerar 100 000 códigos de n dígitos, em seguida, leva (N-5) ^ 10 palpites. Para descobrir se isso é bom o suficiente, você precisa considerar como seus responde sistema para um palpite errado.

Se um invasor (ou, todos os atacantes combinados) pode perfazer 1000 suposições por segundo, então é claro que n tem de ser bastante grande para impedir um determinado intruso. Se você permanentemente bloquear seu endereço IP depois de 3 suposições incorretas, em seguida, uma vez que um determinado atacante é improvável que tenha acesso a mais do que, digamos, 1000 IP endereços, n = 9 seria suficiente para impedir quase todos os atacantes. Obviamente, se você irá enfrentar ataques distribuídos, ou ataques de um botnet, de 1000 endereços IP por atacante já não é uma suposição segura.

Se no futuro você precisa emitir outros códigos (mais de 100 000), então, obviamente, você torna mais fácil de adivinhar um código válido. Por isso é provavelmente vale a pena gastar algum tempo certificando-se de suas necessidades futuras de escala antes de fixar em um tamanho.

Dado o seu caso de uso zero-card, se os usuários vão usar o sistema por um longo tempo, eu recomendaria permitindo-lhes (ou forçando-os) para "atualizar" o seu código PIN para um nome de usuário e senha de sua escolha depois o primeiro uso do sistema. Então você obter as vantagens habituais de nome de usuário / senha, sem descartar a facilidade de primeiro uso de apenas digitando o número fora do cartão.

Quanto à forma de gerar o número - presumivelmente cada um que você gerar você vai armazenar, caso em que eu diria que gerá-los aleatoriamente e duplicatas de descarte. Se você gerá-los usando qualquer tipo de algoritmo, e alguém descobrir o algoritmo, em seguida, eles podem descobrir códigos PIN válidos. Se você selecionar um algoritmo de tal forma que não é possível para alguém para descobrir o algoritmo, em seguida, que quase é um gerador de números pseudo-aleatório (a outra propriedade de PRNGs sendo que eles estão distribuídos uniformemente, que aqui também ajuda, uma vez que torna mais difícil de adivinhar códigos), caso em que você pode muito bem gerar-los aleatoriamente.

Se você usa algoritmos gerador de números aleatórios, para que não tenha PIN como "00038384882", começa com 0 (zero), porque os números inteiros não começa com "0". o PIN deve ser iniciado com 1-9 números exceto 0.

Eu tenho visto muitos números PIN incluir e começa muitos zeros, para que eliminar primeiro milhão de números. necessidade de permutação para cálculos de quantos números eliminado.

Eu acho que você precisa colocar 0-9 números em um hash, e obter por acaso a partir de hash, e fazer o seu número da corda PIN.

Se você quiser gerar códigos de tipo zero-PIN do cartão, então você deve usar um grande número, cerca de 13 dígitos de comprimento; e também, eles devem ser semelhantes aos números de cartão de crédito, com uma soma de verificação ou verificação dígitos incorporado no próprio número. Você deve ter um algoritmo para gerar um pino com base em alguns dados iniciais, que podem ser uma sequência de números. O pino resultante deve ser único para cada número na sequência, de modo que se você gerar 100.000 códigos pin todos eles devem ser diferentes. Desta forma, você será capaz de validar um número não apenas verificando-la contra um banco de dados, mas você pode verificá-lo primeiro.

Uma vez eu escrevi algo para o efeito, não posso dar-lhe o código, mas a idéia geral é o seguinte:

  • Preparar um espaço de 12 dígitos
  • Formate o número de cinco dígitos (00000 a 99999) e espalhá-lo ao longo do espaço de uma certa maneira. Por exemplo, o número 12345 pode ser transmitida como __3_5_2_4__1. Você pode variar a maneira de espalhar o número dependendo se é um número par ou ímpar, ou um múltiplo de 3, etc.
  • Com base no valor de alguns dígitos, gerar mais dígitos (por exemplo, se o terceiro dígito é ainda, em seguida, criar um número impar e colocá-lo no primeiro espaço aberto, de outro modo criar um número par e colocá-lo no segundo aberto espaço, por exemplo _83_5_2_4__1
  • Depois de ter gerado 6 dígitos, você terá apenas um espaço aberto. Você deve sempre deixar o mesmo espaço aberto (por exemplo, o seguinte-à-último espaço). Você vai colocar o dígito de verificação naquele lugar.
  • Para gerar o dígito de verificação que você deve executar algumas operações aritméticas sobre o número de ter gerado, por exemplo, adicionando todos os dígitos nas posições ímpares e multiplicando-os por algum outro número, em seguida, subtraindo todos os dígitos nas posições mesmo, e finalmente, a adição de todos os dígitos juntos (você deve variar o algoritmo um pouco com base no valor de determinados dígitos). No final, você tem um dígito de verificação que você incluir o código PIN gerado.

Então, agora você pode validar os seus códigos PIN gerado. Para um determinado código pin, você gera o dígito de verificação e verificar se contra o incluído no pino. Se é OK, então você pode extrair o número original, executando as operações inversas.

Ele não soa tão bom porque ele se parece com segurança através da obscuridade, mas é a única maneira que você pode usar isso. Não é impossível para alguém adivinhar um código pin, mas sendo um código de 12 dígitos com um dígito de verificação, que vai ser muito difícil, pois você tem que tentar 1.000.000.000.000 combinações e você só tem 100.000 códigos PIN válido, então para cada código PIN válido lá são 10.000.000 os inválidos.

Eu devo mencionar que esta é útil para códigos PIN descartáveis; uma pessoa usa um desses códigos de uma única vez, por exemplo, para carregar um telefone pré-pago. Não é uma boa idéia usar estes pinos como tokens de autenticação, especialmente se é a única maneira para autenticar alguém (você nunca deve alguém sempre autenticar apenas através de uma única peça de dados; o mínimo é nome de usuário + senha)

Parece que você deseja usar o código pin como os únicos meios de identificação para os usuários. Uma solução viável seria usar os cinco primeiros dígitos para identificar o usuário, e anexação de quatro dígitos como um código PIN.

Se você não deseja armazenar PINs podem ser calculadas através da aplicação de um hash criptograficamente segura (SHA1 ou melhor) para o número de usuários, mais de um código de todo o sistema secreto.

Eu deveria gerar este código através de algum tipo de algoritmo?

No. Será previsível.

Ou devo aleatoriamente gerá-lo?

Sim. Use um gerador aleatório de criptografia, ou deixar o usuário escolher o seu próprio PIN.

Em teoria 4 dígitos será abundância como os emissores de cartões ATM conseguem suportar uma comunidade muito grande com apenas isso (e, obviamente, eles não podem ser e não precisa ser exclusivo). No entanto, nesse caso, você deve limitar o número de tentativas de introdução do PIN e bloqueá-los para fora depois que muitas tentativas como os bancos fazem. E você também deve obter o usuário para fornecer um ID de usuário (no caso ATM, que é eficaz no cartão).

Se você não quer limitar-los dessa forma, pode ser melhor para abandonar a idéia PIN e usar uma senha padrão (que é essencialmente o que o seu PIN é, apenas com um comprimento muito curto e conjunto limitado de caracteres) . Se você absolutamente deve limitar a numerics (porque você tem uma almofada PIN ou algo assim), em seguida, considere fazer 4 um comprimento (configurável) mínimo em vez do que o comprimento fixo.

Você não deve armazenar o PIN em qualquer lugar clara (por exemplo, sal e hash como uma senha), no entanto, dada a curta duração e de char limitada defini-lo é sempre vai ser vulnerável a uma pesquisa de força bruta, dada uma maneira fácil para verificar-lo.

Existem vários outros esquemas que podem ser utilizados, bem como, se você pode nos dizer mais sobre suas necessidades (é este um aplicativo web? Sistema embarcado? Etc).

Há uma diferença entre adivinhar o PIN de um usuário de destino, e que de qualquer user válido. De seu caso de uso, parece que o PIN é usado para ganhar acesso a determinado recurso, e é esse recurso que os atacantes podem ser depois, não identidades particulares dos usuários. Se isso é realmente o caso, você vai precisar fazer números PIN válidos suficientemente escassa entre todos os números possíveis dos mesmos dígitos de um número.

Como mencionado em algumas respostas, você precisa fazer o seu PIN suficientemente aleatória, independentemente se você quiser gerá-lo a partir de um algoritmo. A aleatoriedade é geralmente medido pelo entropia do PIN.

Agora, vamos dizer que seu PIN é da entropia N , e há 2 ^ M usuários em seu sistema ( M ) , a probabilidade de que um palpite aleatório irá produzir um PIN válido é 2 ^ {MN} . (Desculpe para as notações de látex, eu espero que seja o suficiente intuitivo). Em seguida, a partir daí você pode determinar se essa probabilidade é baixa o suficiente dada N e M , ou calcular o necessário N na probabilidade desejada e M .

Existem várias maneiras de gerar os PINs de modo que você não terá que se lembrar de cada PIN gerado. Mas você vai precisar de um tempo muito longo PIN para torná-lo seguro. Isto provavelmente não é o que você quer.

Já fiz isso antes com PHP e um banco de dados MySQL. Eu tinha permutações funcionar que primeiro garantir que o número de códigos necessários - $ n, no comprimento $ l, com o número de caracteres, $ c -. Foi capaz de ser criado antes de iniciar o processo de geração

Então, eu armazenar cada novo código para o banco de dados e deixe-me dizer via erros chave única, que houve uma colisão (duplicado). Então continue indo até que eu tinha feito $ n número de códigos criados com sucesso. Você poderia naturalmente fazer isso na memória, mas eu queria manter os códigos para uso em uma mala direta MS Word. Então ... então eu exportado-los como um arquivo CSV.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top