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 / 56844
Accepted
efesar
efesar
Asked: 2014-01-16 11:23:24 +0800 CST2014-01-16 11:23:24 +0800 CST 2014-01-16 11:23:24 +0800 CST

Existe uma maneira rápida de localizar todas as colunas no SQL Server 2008 R2 que são criptografadas/têm dados criptografados?

  • 772

Existe uma maneira rápida de localizar todas as colunas no SQL Server 2008 R2 que são criptografadas/têm dados criptografados?

Preciso anular os dados em todas as colunas criptografadas em um servidor de desenvolvimento (de acordo com nossas regras de negócios). Conheço a maioria das colunas porque as usamos regularmente, mas quero ser minucioso e também quero poder provar que encontrei todas elas.

Pesquisei na web, procurei em INFORMATION_SCHEMA e verifiquei os DMVs que pensei que seriam úteis e também sys.columns e sys.objects - mas até agora sem sorte.

sql-server sql-server-2008-r2
  • 4 4 respostas
  • 8312 Views

4 respostas

  • Voted
  1. Best Answer
    Edward Dortland
    2014-01-17T06:17:03+08:002014-01-17T06:17:03+08:00

    Supondo que você esteja falando sobre dados criptografados com chaves do SQL Server, existe uma maneira de encontrar essas colunas.

    A Key_name()função retornará o nome da chave usada para a criptografia para esse valor específico e retornará NULL se não houver nada criptografado com uma chave "conhecida" (de terceiros ou simples não criptografada).

    Com esse conhecimento podemos testar cada coluna para ver se contém pelo menos uma linha que tenha um valor varbinary que retorne um nome de chave

    funcionalidade de key_name()

    --create a test database
    CREATE DATABASE [Test_ENCR]
    GO
    
    --change context
    USE [Test_ENCR]
    GO
    
    
    --because it's possible to encrypt different rows with different keys I'll create 2 keys for this demo
    -- Create a symmetric key
    CREATE SYMMETRIC KEY symmetricKey1
       WITH ALGORITHM = AES_128
       ENCRYPTION BY PASSWORD = 'password01!';
    GO
    
    -- Create a second key
    CREATE SYMMETRIC KEY symmetricKey2 
       WITH ALGORITHM = AES_128
       ENCRYPTION BY PASSWORD = 'password02!';
    GO
    
    
    
    --create a table that will have a column holding:
    --1: encrypted row with key1
    --2: encrypted row with key2
    --3: a non encrypted just varbinary value
    
    CREATE TABLE encryptedTable
    (ID int IDENTITY PRIMARY KEY,
    EncryptedCol varbinary(256) NOT NULL);
    GO
    
    
    -- open key1
    OPEN SYMMETRIC KEY symmetricKey1 
        DECRYPTION BY PASSWORD = 'password01!';
    GO
    
    -- open key2
    OPEN SYMMETRIC KEY symmetricKey2 
        DECRYPTION BY PASSWORD = 'password02!';
    GO
    
    --insert encrypted data with key1
    INSERT INTO encryptedTable(encryptedCol)
    VALUES ( ENCRYPTBYKEY (Key_GUID('symmetricKey1'), 'EncryptedText1'));
    GO
    
    --insert encrypted data with key2
    INSERT INTO encryptedTable(encryptedCol)
    VALUES ( ENCRYPTBYKEY (Key_GUID('symmetricKey2'), 'EncryptedText2'));
    GO
    
    
    --insert just varbinary data
    INSERT INTO encryptedTable(encryptedCol)
    VALUES (CONVERT(varbinary(256),'NotEncryptedTextJustVarBinary'))
    
    
    
    --have a look, without the key, all varbinary for you.
    SELECT * FROM encryptedTable
    GO
    

    resultados:

    insira a descrição da imagem aqui

    --Return all key_names
    SELECT DISTINCT     key_name(encryptedcol), 
                        EncryptedCol 
    FROM encryptedTable;
    

    resultados:

    insira a descrição da imagem aqui

    Como implementá-lo para encontrar colunas criptografadas

    --How do we dynamically find all the columns that have at least one row with a encrypted value?
    
    -- first we will find all tables and column with a varbinary datatype
    -- then we will test all those columns with a simple select
    -- If the key_name() function returns a value, the column and table name are stored together with the keyname
    
    --create a table to hold all varbinary columns and tables
    CREATE TABLE #TablesWithVarbinCols (    ID int IDENTITY,
                                    TableName nvarchar(128),
                                    ColumnName nvarchar(128)
                                    );
    
    --create a table to hold the end result
    CREATE TABLE #TablesWithEncryption (
                                    TableName nvarchar(128),
                                    ColumnName nvarchar(128),
                                    KeyName varchar(128)
                                    );
    
    
    --find and store all table and column names of user tables containing a varbinary column
    INSERT INTO #TablesWithVarbinCols (TableName,ColumnName)
    SELECT      o.[name] as TableName,
                c.[name] as ColumnName
    FROM        sys.objects o
    INNER JOIN  sys.columns c
    ON          o.[object_id]=c.[object_id] 
    INNER JOIN  sys.types t
    ON          c.system_type_id=t.system_type_id
    WHERE       o.[type]='U'
    AND         t.name=N'varbinary'
    AND         c.max_length > -1;
    
    
    DECLARE @col nvarchar(256)
    DECLARE @tab nvarchar(256)
    DECLARE @c int = 1
    DECLARE @MaxC int
    DECLARE @SQL varchar(max)
    
    SELECT @MaxC=MAX(ID)
    FROM #TablesWithVarbinCols
    
    --loop the previous result and create a simple select statement with a key_name() is not null where clause. 
    --If you have a result, store the details
    WHILE @c <= @MaxC
    BEGIN
        SELECT  @Tab=TableName,
             @col=ColumnName
        FROM    #TablesWithVarbinCols
        WHERE   ID=@c
    
        SET @SQL='  INSERT INTO #TablesWithEncryption (TableName, ColumnName, KeyName)
                    SELECT DISTINCT '''+@Tab +''',''' +@col +''', key_name('+@Col +') from '+ @tab +' 
                    WHERE key_name('+@Col +') is not null;'
        exec (@SQL)
    
        DELETE
        FROM #TablesWithVarbinCols
        WHERE id=@c;
        SET @c=@c+1
    END
    
    --select the result
    SELECT * FROM #TablesWithEncryption;
    

    resultados:

    insira a descrição da imagem aqui

    --cleanup
    DROP TABLE #TablesWithVarbinCols;
    DROP TABLE #TablesWithEncryption;
    
    • 11
  2. Mike Fal
    2014-01-16T11:47:30+08:002014-01-16T11:47:30+08:00

    O problema com a criptografia no nível da célula é que a coluna em si não é realmente criptografada, são os dados contidos nessa coluna. As próprias colunas são apenas colunas varbinárias (porque é isso que é necessário) e podem conter dados completamente legíveis. É o uso das funções ENCRYPTBY*e DECRYPTBY*que realmente tornam os dados criptografados.

    Você pode começar simplesmente consultando a exibição sys.columns para todas as colunas que são varbinárias:

    select
      object_name(a.object_id) [objectname]
      ,a.name [columnname]
      ,a.column_id
    from
       sys.columns a
       join sys.types b on (a.system_type_id = b.system_type_id)
    where
       b.name = N'varbinary';
    

    Caso contrário, você precisará revisar seu código para identificar onde as funções de criptografia/descriptografia estão sendo usadas:

    select
       object_name(object_id) [objectname]
       ,definition
    from
       sys.sql_modules
    where
       definition like N'%ENCRYPT%' 
       OR definition like N'%DECRYPT%';
    
    • 8
  3. roncansan
    2018-09-15T11:18:00+08:002018-09-15T11:18:00+08:00

    Execute a consulta abaixo em um banco de dados específico

    select 
        t.name as [Table],
        c.name as [Column], 
        c.encryption_type_desc
    from   
        sys.all_columns c inner join
        sys.tables t on c.object_id = t.object_id
    where  
        c.encryption_type is not null 
    order by
        t.name,
        c.name
    

    Ligeiramente alterado de

    https://social.msdn.microsoft.com/Forums/sqlserver/en-US/ca9d8360-5d7e-4de1-abe6-ce1afda595a9/how-to-find-which-table-columns-are-encrypted?forum=sqlsecurity

    • 1
  4. matzek
    2018-11-10T07:51:25+08:002018-11-10T07:51:25+08:00

    Você pode localizar as colunas criptografadas com keys\certificates pesquisando todas as colunas varbinary e verificando uma chave de criptografia com a função KEY_NAME.

    No entanto, este processo é um pouco caro e demorado. Se você precisar localizar essas colunas regularmente, sugiro "marcar" as colunas com propriedades estendidas. Podemos desenvolver a solução de Edward Dortland e "marcar" as colunas encontradas com propriedades estendidas como criptografado, encryptkey e encryptcert.

    --create a table to hold all varbinary columns and tables
    CREATE TABLE #TablesWithVarbinCols (    ID int IDENTITY,
                                SchemaName nvarchar(128),
                                TableName nvarchar(128),
                                ColumnName nvarchar(128)
                                );
    
    --find and store all table and column names of user tables containing a 
    varbinary column
    INSERT INTO #TablesWithVarbinCols (SchemaName,TableName,ColumnName)
    SELECT      s.[name] as SchemaName,
                o.[name] as TableName,
                c.[name] as ColumnName
    FROM        sys.objects o
    INNER JOIN  sys.schemas s
    ON          s.[schema_id] = o.[schema_id]
    INNER JOIN  sys.columns c
    ON          o.[object_id]=c.[object_id] 
    INNER JOIN  sys.types t
    ON          c.system_type_id=t.system_type_id
    WHERE       o.[type]='U'
    AND         t.name=N'varbinary'
    AND         c.max_length > -1;
    
    DECLARE @sch nvarchar(128)
    DECLARE @col nvarchar(256)
    DECLARE @tab nvarchar(256)
    DECLARE @key nvarchar(256)
    DECLARE @cert nvarchar(256)
    DECLARE @c int = 1
    DECLARE @MaxC int
    DECLARE @SQL nvarchar(max)
    
    SELECT @MaxC=MAX(ID)
    FROM #TablesWithVarbinCols
    
    --loop the previous result and create a simple select statement with a 
    key_name() is not null where clause. 
    --If you have a result, store the details
    WHILE @c <= @MaxC
    BEGIN
        SET @key = NULL;
        SELECT  @sch=SchemaName,
                @Tab=TableName,
                @col=ColumnName
        FROM    #TablesWithVarbinCols
        WHERE   ID=@c
    
    
    SET @SQL='SELECT DISTINCT @key= key_name('+@Col +') from '+ @tab +' 
                WHERE key_name('+@Col +') is not null;'
    
    
    exec sp_executesql @SQL, N'@key nvarchar(256) out', @key out
    
    SELECT @cert =  c.name 
    from sys.symmetric_keys sk
    join sys.key_encryptions ke
        on
        sk.symmetric_key_id= ke.key_id
    join sys.certificates c
        on
        ke.thumbprint=c.thumbprint
    where sk.name = @key
    
    
    IF (@key IS NOT NULL)
    BEGIN
    
        SET @SQL=
        'EXEC sp_addextendedproperty @name = N''encrypted'', @value = N''1'', '+
        '@level0type = N''Schema'', @level0name = '''+@Sch+''', '+
        '@level1type = N''Table'', @level1name = '''+@tab+''','+
        '@level2type = N''Column'', @level2name = '''+@col+'''
        '
    
        EXEC sp_executesql @SQL
    
        SET @SQL=
        'EXEC sp_addextendedproperty @name = N''encryptkey'', @value = '''+@key+''', '+
        '@level0type = N''Schema'', @level0name = '''+@Sch+''', '+
        '@level1type = N''Table'', @level1name = '''+@tab+''','+
        '@level2type = N''Column'', @level2name = '''+@col+'''
        '
    
        EXEC sp_executesql @SQL
    
        SET @SQL=
        'EXEC sp_addextendedproperty @name = N''encryptcert'', @value = '''+@cert+''', '+
        '@level0type = N''Schema'', @level0name = '''+@Sch+''', '+
        '@level1type = N''Table'', @level1name = '''+@tab+''','+
        '@level2type = N''Column'', @level2name = '''+@col+'''
        '
    
        EXEC sp_executesql @SQL
    
    END
    
    DELETE
    FROM #TablesWithVarbinCols
    WHERE id=@c;
    SET @c=@c+1
    
    END
    
    drop table #TablesWithVarbinCols
    

    Em seguida, podemos encontrar facilmente as colunas criptografadas pesquisando as propriedades estendidas.

    --Adjust WHERE clause depending on what tags you are looking for
    SELECT
       SCHEMA_NAME(tbl.schema_id) AS SchemaName,    
       tbl.name AS TableName, 
       clmns.name AS ColumnName,
      p.name AS ExtendedPropertyName,    --remove for programming
       CAST(p.value AS sql_variant) AS ExtendedPropertyValue
    FROM
       sys.tables AS tbl
       INNER JOIN sys.all_columns AS clmns ON clmns.object_id=tbl.object_id
       INNER JOIN sys.extended_properties AS p ON p.major_id=tbl.object_id AND p.minor_id=clmns.column_id AND p.class=1
    WHERE p.name in ('encrypted','encryptkey','encryptcert')
    
    • 1

relate perguntas

  • SQL Server - Como as páginas de dados são armazenadas ao usar um índice clusterizado

  • Preciso de índices separados para cada tipo de consulta ou um índice de várias colunas funcionará?

  • Quando devo usar uma restrição exclusiva em vez de um índice exclusivo?

  • Quais são as principais causas de deadlocks e podem ser evitadas?

  • Como determinar se um Índice é necessário ou necessário

Sidebar

Stats

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

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 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

    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
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • 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
    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