AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 36416
Accepted
Marek
Marek
Asked: 2013-03-12 02:49:57 +0800 CST2013-03-12 02:49:57 +0800 CST 2013-03-12 02:49:57 +0800 CST

Qual é a melhor maneira de armazenar o certificado X509 no banco de dados PostgreSQL?

  • 772

Estou trabalhando em um sistema de autenticação na Web em que os usuários assinarão digitalmente tokens aleatórios e isso será verificado com certificados X509 armazenados no servidor.

Portanto, tenho que armazenar vários certificados X509 (formato PEM ou DER) no banco de dados PostgreSQL. Parece fácil, mas quero ter a possibilidade de pesquisar certificados com assunto, emissor, notBefore, notAfter e critérios semelhantes.

Minha ideia é ter as seguintes colunas no banco de dados: X509data, notAfter, notBefore, subject, issuer etc. Então criarei um objeto (na alquimia SQL) representando o certificado X509 com métodos como add_new_X509(), find_X509(critérios de pesquisa) etc. Adicionarei um novo certificado com o método add_new_X509(), ele lerá automaticamente todos os dados do certificado e preencherá o restante das colunas e colocará o certificado bruto na coluna X509data.

Infelizmente, esta solução tem duas desvantagens:

  1. Vou armazenar as mesmas informações duas vezes (no próprio certificado X509 e em colunas separadas para facilitar a pesquisa)
  2. Sempre que eu quiser ler o certificado X509, meu aplicativo terá que verificar notAfter, notBefore, assunto, emissor com as informações armazenadas no certificado original (isso é por motivos de segurança, caso alguém tente modificar esses campos).

Então... alguém tem uma ideia melhor ou sugestão? Talvez alguém veja algum outro problema de segurança que possa surgir com esta solução?

postgresql python
  • 4 4 respostas
  • 8083 Views

4 respostas

  • Voted
  1. Best Answer
    Craig Ringer
    2013-03-12T03:46:32+08:002013-03-12T03:46:32+08:00

    A duplicação não é o ideal, mas neste caso é provavelmente a melhor escolha. Defina as permissões da tabela para que o proprietário da tabela não seja o usuário operacional diário do banco de dados com o qual seu aplicativo é executado e apenas GRANTseu aplicativo a capacidade de gravar na coluna de dados do certificado, não nas colunas de "cache" com expiração etc. Tenha um SECURITY DEFINERgatilho A função interceptar grava no campo do certificado e, como um usuário privilegiado, atualiza as colunas de cache indexadas usando uma biblioteca X.509 para extrair os campos do certificado depois de verificá-lo.

    Como alternativa, você pode escrever uma função PL/Python, PL/Perl ou até mesmo uma função C SQL que chama uma biblioteca de analisador de certificados X.509 para extrair campos e retorná-los. Então você diria extract_x509_field(cert, 'subject'). Ou talvez até mesmo um formulário de retorno de linha como SELECT subject, issuerName FROM (SELECT extract_x509_fields(cert) FROM the_table)where extract_x509_fieldsretorna uma linha de todos os dados de certificado relevantes. Com essa abordagem, você pode criar índices funcionais como os CREATE INDEX cert_issuer ON certificate_table( extract_x509_field(cert,'issuer') );que podem ser usados ​​para corresponder a WHEREexpressões. Você não precisaria ter colunas de tabela para os dados extraídos. A desvantagem é que isso provavelmente seria mais lento, pois o certificado seria analisado várias vezes durante a criação do índice, durante as novas verificações do índice, etc.

    De qualquer forma, é vital que seu aplicativo opere como um usuário do PostgreSQL que não seja o proprietário do banco de dados, não seja um superusuário e não seja o proprietário das tabelas e índices em questão. Devem ser GRANTconcedidos os direitos mínimos necessários e nada mais. Se você tiver tarefas bastante separadas (digamos, somente leitura versus gravação e atualização), considere usar diferentes usuários de banco de dados para elas, de modo que, mesmo que a parte "leitura" do seu aplicativo seja enganada para tentar gravar um campo/atualizar um certificado /etc, ele não tem permissão para isso.

    • 6
  2. bgiles
    2015-09-09T08:37:11+08:002015-09-09T08:37:11+08:00

    Abordei um problema semelhante em meu blog Armazenando certificados digitais X.509 (e outras coisas confusas) e alguns comentários anteriores. (É muito longo recortar e colar aqui.) Muitos dos pontos levantados aqui são muito mais fáceis se você puder criar uma função definida pelo usuário que extraia os campos que você precisa armazenar em cache.

    Abordando um outro ponto acima - é possível escrever um gatilho que usa SPI para verificar se o emissor do certificado está presente no banco de dados. Você precisaria incluir exceções para certificados raiz autoassinados e certificados 'confiáveis' fornecidos por outros. Isso, mais algumas outras verificações de sanidade (por exemplo, o emissor tem a capacidade 'básica'? Existem restrições de DN?) daria a você um repositório muito mais forte.

    É sábio fazer isso? Eu continuo indo e voltando sobre isso. Meus pensamentos atuais são de que funcionaria se você emitisse e gerenciasse seus próprios certificados, mas seria uma grande dor de cabeça se você incorporasse certificados de terceiros. O problema é que existem muitos certificados viciados por aí. Se você for rigoroso, excluirá muitos certificados em uso e, se for negligente, por que se preocupar com a lógica extra?

    • 3
  3. Burhan Khalid
    2013-03-12T03:40:54+08:002013-03-12T03:40:54+08:00

    Não entendi bem por que você deseja armazenar os vários campos de assunto/emissor separadamente, a menos que vá consultar as informações do banco de dados; especialmente porque você terá que ler o certificado para verificar seus detalhes (seu segundo item da lista).

    Se você estiver armazenando isso para expirar/invalidar certificados automaticamente, poderá executar uma tarefa separada que faça isso.

    Além disso, como o postgresql permite que você use python como uma linguagem de procedimento; você pode escrever um gatilho ou exibição que retornará as informações "analisadas" para seu aplicativo - se você realmente quiser descarregá-las de seu aplicativo.

    Além disso, eu faria o seguinte, já que você está armazenando certificados:

    1. Certifique-se de que a conexão entre os clientes e o servidor esteja criptografada (você deve fazer isso de qualquer maneira). Consulte a seção 17.9 na documentação.

    2. Certifique-se de que a tabela/coluna esteja criptografada. Consulte a pycryptodocumentação do módulo.

    • 1
  4. Chris Travers
    2013-03-12T18:06:07+08:002013-03-12T18:06:07+08:00

    Acrescentando à excelente resposta de Craig, que uma vez que você começa a extrair informações de uma biblioteca X509, você pode fazer outras coisas interessantes com ela. Não sei se o SQLAlchemy sempre usa aliases de tabela ou se você pode forçá-lo a fazê-lo, mas se puder, evite a duplicação de informações chamando as rotinas de análise diretamente nos certificados X509 e até indexe a saída dessas funções para que você não precise chamá-las no horário selecionado (ou seja, as funções são executadas no horário de inserção/atualização), como ele menciona.

    Uma coisa que gostaria de apontar é que você pode criar métodos de tabela que, se você conseguir que seu ORM sempre use aliases de tabela, poderá substituir as colunas. Por exemplo:

    CREATE OR REPLACE FUNCTION issuer(x509table) returns text 
    LANGUAGE SQL IMMUTABLE AS $$
        select issuer_cn FROM extract_x509info($1.x509data);
    $$;
    

    Isso pode ser encontrado por:

    SELECT x.issuer FROM x509table x;  --works
    

    Observe que o seguinte não é válido e, portanto, meus comentários sobre o ORM:

    SELECT issuer FROM x509table; --does not work
    

    O motivo é que, se não houver coluna do emissor, o analisador converterá a primeira instrução para:

    SELECT issuer(x) from x509table x;
    

    Observe que a indexação de muitas colunas mudará muito o tempo de computação de leitura para gravação (tornando inserções/atualizações mais lentas, mas operações de leitura mais rápidas).

    No final, é difícil chegar a uma recomendação completa sem saber exatamente o que você está fazendo, quais são as cargas de trabalho esperadas etc. A vantagem da duplicação é separar os dados das funções de extração para leitura e gravação, permitindo mais otimizações ser possível. A vantagem de manter tudo funcional (supondo que seu ORM suporte isso) é que ele fornece garantias adicionais de integridade de dados.

    • 1

relate perguntas

  • Posso ativar o PITR depois que o banco de dados foi usado

  • Práticas recomendadas para executar a replicação atrasada do deslocamento de tempo

  • Os procedimentos armazenados impedem a injeção de SQL?

  • Sequências Biológicas do UniProt no PostgreSQL

  • Qual é a diferença entre a replicação do PostgreSQL 9.0 e o Slony-I?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Conceder acesso a todas as tabelas para um usuário

    • 5 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    pedrosanta Listar os privilégios do banco de dados usando o psql 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve