Aprimoramentos de Criptografia: Suporte a Procedimento de Campo no DB2 para i 7.1

Proteja seus Aplicativos IBM i

Suporte à criptografia no nível da coluna é um dos principais recursos de título do DB2 ® no release do IBM® i 7.1. O suporte do DB2 para i 7.1 possibilita implementações transparentes de criptografia no nível da coluna com uma rotina de saída no nível do campo conhecida como um procedimento de campo. Descubra como esse interessante suporte permite que desenvolvedores criem, de forma mais fácil e flexível, um aplicativo seguro.

Xing Xing Shen, Staff Software Engineer, IBM

Author photo of Xing ShenXing Xing Shen é engenheira de software de equipe em CSTL em Pequim. Ela trabalha em teste de DB2 para IBM i há mais de cinco anos. Suas responsabilidades profissionais incluem FVT de banco de dados e teste de regressão.



Jia Tian Zhong, Staff Software Engineer, IBM

Author photo of Jia ZhongJia Tian Zhong trabalha na equipe de Investigação de Desempenho do DB2 para a IBM em CSTL. Antes de trabalhar no DB2, ele trabalhava na programação de aplicativos RPG em sistemas AS/400.



Shu Pang, Software Engineer, IBM

Author photo of Shu PangShu Pang é engenheiro de software em CSTL em Pequim. Ele trabalha em teste de DB2 para IBM i há mais de dois anos. Suas responsabilidades profissionais incluem FVT de banco de dados e teste de regressão.



Carol L Ramler, Senior Software Engineer, IBM

Author photo of Carol RamlerCarol Ramler é engenheira de software senior na IBM Rochester, Minnesota. Ela trabalha nas áreas de DB2 para i5/OS há mais de 22 anos.



27/Jan/2011

Introdução

Problemas de segurança sempre estiveram entre os principais tópicos, mas adquiriram mais importância nos últimos anos. As empresas devem estar em conformidade com os regulamentos dos segmentos de mercado e dos governos para assegurarem que suas informações sigilosas, como números de cartões de crédito, números de seguridade social, informações de folha de pagamento, informações relacionadas à saúde, etc., sempre estejam seguras. Para que se obtenha isso, uma solução forte de criptografia de dados é indispensável.

Nas versões do DB2 para i anteriores à versão 7.1, acionadores de colunas eram utilizados para automatizar criptografia. Apesar de interfaces nativas não SQL não poderem decriptografar dados automaticamente, as interfaces SQL podiam usar uma visualização SQL semitransparente para a decriptografia, mas esse método exigia muito esforço e era inconveniente.

O release do DB2 para i 7.1 fornece uma tecnologia de ativação conhecida como um procedimento de campo (FieldProc) para fornecer implementações transparentes de criptografia no nível da coluna. Usando a cláusula FIELDPROC de CREATE TABLE e ALTER TABLE, é possível registrar um procedimento de campo em uma coluna. Um procedimento de campo é uma rotina de saída escrita pelo usuário projetada para transformar valores em uma única coluna. Quando valores da coluna são alterados ou novos valores são inseridos, o procedimento de campo é chamado para cada valor e pode transformar esse valor (codificá-lo) de qualquer forma e, em seguida, armazená-lo. Quando valores são recuperados da coluna, o procedimento de campo é chamado para cada valor codificado, que então os decodifica novamente de volta ao valor original. Quaisquer índices definidos em uma coluna não derivada que usa um procedimento de campo são desenvolvidos com valores codificados.

Vantagens do Suporte ao Procedimento de Campo

Os benefícios do novo suporte à criptografia do procedimento de campo apresentado no DB2 para i 7.1 são os seguintes:

  • Criptografia segura. Dados, índices e diários armazenados em discos rígidos ou fitas são uma versão transformada (criptografada) dos dados. Ninguém pode obter os dados decriptografados sem o programa FieldProc.
  • Uso facilitado. Para ativar o procedimento de campo, é necessário apenas escrever um programa FieldProc (ou chamar funções de criptografia/decriptografia de terceiros) e, em seguida, registrá-lo na tabela.
  • Mais flexibilidade. É possível alterar facilmente para outros métodos de criptografia incluindo, eliminando ou movendo para outros programas FieldProc. Observe que apesar de um valor codificado poder ser mais longo do que o valor definido do campo, ele é flexível e pode ser alterado com programas FieldProc. Nenhuma alteração da definição de tabela original é necessária.

Considerações sobre Desempenho do Suporte ao Procedimento de Campo

Embora os procedimentos de campo permitem que você implemente criptografia e decriptografia de forma transparente sem mudanças de aplicativos, essa flexibilidade não tem uma compensação de desempenho. Registrar programas de procedimento de campo inclui sobrecarga, semelhante àquela de uma chamada de programa externo, em cada interface que grava ou lê valores dessa coluna. As operações executadas pelo programa de procedimento de campo em si também serão um fator na sobrecarga do desempenho. Por exemplo, o processamento de criptografia e decriptografia são notórios pela quantia de ciclos de CPU que demandam. Assim, o teste de desempenho deve ser uma parte crítica da sua implementação do procedimento de campo.

Como Usar FieldProc

Como um desenvolvedor de aplicativos, você pode simplesmente usar a cláusula FIELDPROC para registrar o procedimento de campo em uma tabela. No exemplo a seguir, uma tabela de funcionários é criada com dados sensíveis (salário) que são criptografados por um procedimento de campo:

 Create TABLE employee ( ID char(10),
        salary decimal(10,2) FieldProc FP.userpgm )

Ou uma tabela de funcionários existente pode ser alterada para criptografar os dados sensíveis na coluna salary:

 ALTER TABLE employee alter column
        salary set FieldProc FP.userpgm //We can alter to add a FieldProc on
        both SQL table and Native table.

É claro que o procedimento de campo também pode ser eliminado e é possível usar outro procedimento de campo para criptografar os dados sensíveis:

 ALTER TABLE FP.userpgm alter column
        salary drop FieldProc // drop the old field procedure ALTER TABLE
        employee alter column salary set FieldProc FP.userpgm2 //then add the
        new one

Restrições de Atributos de Coluna Suportados

O DB2 para i 7.1 suporta a criptografia de qualquer tipo de dado com procedimentos de campo, exceto ROWID, IDENTITY e ROW CHANGE TIMESTAMP.

Notas: Somente uma coluna LOB pode ser incluída com FieldProc em cada tabela.

Quando procedimentos de campo são chamados

Um procedimento de campo especificado para uma coluna é chamado em três situações gerais:

  • No caso de definição de campo, quando a instrução CREATE TABLE ou ALTER TABLE que denomina o procedimento é executada. Durante essa chamada, espera-se que o procedimento determine a validade de tipo de dados e atributos da coluna, verifique a lista de literais e forneça a descrição do campo da coluna.
  • No caso de codificação de campo, quando um valor de coluna for ser codificado pelo campo. Isso ocorre para qualquer valor inserido por uma instrução SQL INSERT ouMERGE , por uma gravação nativa, é alterado por atualização ou os dados são copiados para uma coluna de destino com um procedimento de campo registrado.
  • No caso de decodificação de campo, quando um valor armazenado for ser decodificado pelo campo de volta para seu valor original. Isso ocorre para qualquer valor recuperado por uma instrução SQL SELECT ou FETCH , por uma leitura nativa, ou os dados são copiados para uma coluna de destino sem um procedimento de campo registrado.

Como gravar um programa de procedimento de campo

Três amostras de código são fornecidas na próxima seção para ilustrar a implementação típica do programa FieldProc.

Antes de apresentar o programa de procedimento de campo, é necessário explicar diversos novos termos chave listados abaixo. Para as informações detalhadas, consulte o SQL Programming Guide.

  • Formato externo: O formato dos dados da coluna que serão recebidos ou retornados do/para o programa do mecanismo de banco de dados.
  • Formato interno: O formato dos dados da coluna como são armazenados internamente pelo mecanismo de banco de dados.
  • Codificação pelo campo: A transformação que seu procedimento de campo executa em um valor.
  • Decodificação pelo campo: A mesma rotina que é usada para desfazer a transformação quando valores são recuperados.
  • Definição de campo: O procedimento de campo também é chamado quando a tabela é criada ou alterada para definir o tipo de dado e os atributos de um valor codificado para o DB2.

    Nota: Um tipo de dado definido pelo usuário pode ser um campo válido se o tipo de dado tiver qualquer um dos tipos de dados SQL permitidos. O DB2 efetua cast do valor da coluna para o tipo de origem antes de passá-lo para o procedimento de campo.

  • Column value descriptor (CVD): Durante a codificação pelo campo o CVD descreve o valor a ser codificado, assim como o valor decodificado a ser fornecido pelo procedimento de campo. Durante a definição de campo, descreve a coluna conforme definida na instrução CREATE TABLE ou ALTER TABLE .
  • Lista de parâmetros do procedimento de campo: A lista de parâmetros do procedimento de campo comunica informações gerais para um procedimento de campo, informa qual operação deve ser efetuada e permite que o procedimento de campo sinalize erros. O DB2 fornece armazenamento para todos os parâmetros que são passados para o procedimento de campo, portanto, parâmetros são passados para o procedimento de campo por endereço.
  • Os oito parâmetros a seguir estão na lista:
    • Parâmetro 1: Um número inteiro pequeno (2 bytes) que descreve a função a ser executada. Esse parâmetro é somente entrada e suporta os seguintes valores:
      • 0 - codificação pelo campo
      • 4 - decodificação pelo campo
      • 8 - definição de campo
    • Parâmetro 2: É uma estrutura que define a field procedure parameter value list (FPPVL). Para o código de função 8, esse parâmetro é entrada/de saída. Para o código de função 0 e 4, esse parâmetro contém a saída da chamada do código de função 8. Esse parâmetro é somente de entrada.
    • Parâmetro 3: É o atributo de dados decodificado que é definido pelo Column Value Descriptor (CVD). São os atributos de coluna que foram especificados no momento de CREATE TABLE ou ALTER TABLE . Esse parâmetro é somente de entrada.
    • Parâmetro 4: São os dados decodificados. O uso desse parâmetro depende do código de função.
    • Parâmetro 5: É o atributo Internal Encoded Data que é definido pelo Field Value Descriptor (FVD).
    • Parâmetro 6: São os dados codificados definidos pelo Field Value Descriptor (FVD). O uso desse parâmetro depende do código de função.
    • Parâmetro 7: O SQLSTATE é caractere(5). Esse parâmetro é entrada/saída.

      Notas: Esse parâmetro é passado do banco de dados configurado para 00000 e pode ser configurado pelo procedimento de campo como um estado de resultado para o procedimento de campo. Apesar de normalmente o SQLSTATE não ser configurado no procedimento de campo, ele pode ser usado para sinalizar para o banco de dados da seguinte forma: 38xxx - o código de função detectou uma situação de erro, resultante em um erro de SQL. Aqui xxx pode ser uma de diversas cadeias de caracteres. Avisos não são suportados para procedimentos de campo.

    • Parâmetro 8: A área de texto da mensagem é VARCHAR(1000). Esse parâmetro é entrada/saída.

      Notas: Esse argumento é configurado pelo DB2 para a cadeia de caracteres vazia antes de chamar o procedimento de campo. É um valor de VARCHAR(1000) que pode ser usado pelo procedimento de campo para enviar texto de mensagem de volta quando um erro de SQLSTATE é sinalizado pelo procedimento de campo. É inicializado pelo banco de dados na entrada para o procedimento de campo e pode ser configurado pelo procedimento de campo com informações descritivas. O texto da mensagem é ignorado pelo DB2, a menos que o parâmetro SQLSTATE seja configurado pelo procedimento de campo. Supõe-se que o texto da mensagem esteja no CCSID da tarefa.

Listagem 1. Esta amostra mostra como usar programas de criptografia/decriptografia ou funções de criptografia/decriptografia para realizar a criptografia. O programa criptografa e decriptografa uma cadeia de 16 caracteres que inclui somente números.
 #include <ctype.h> #include
        <string.h> #include <stdlib.h> #include
        <SQLFP.h> void DESC(unsigned char *data, unsigned char
        *mkey, char ctag[2]) { ... //user created or third party encryption
        algorithm. } main(int argc, void *argv[]) { short *funccode = argv[1];
        sqlfpFieldProcedureParameterList_T *optionalParms = argv[2]; char
        *sqlstate = argv[7]; sqlfpMessageText_T *msgtext = argv[8];
        sqlfpOptionalParameterValueDescriptor_T *optionalParmPtr; char
        KEY[16]="0123456789ABCDEF"; if (*funccode == 8) /* horário de criação */
        { sqlfpParameterDescription_T *inDataType = argv[3];
        sqlfpParameterDescription_T *outDataType = argv[5]; if
        (inDataType->sqlfpSqlType !=452 &&
        inDataType->sqlfpSqlType !=453 ) /* only support fixed length */
        memcpy(sqlstate,"38002",5); /* do something here to determine the result
        data type */ /* ..... */ /* in this example input and output types are
        exactly the same */ /* so just copy */ memcpy(outDataType, inDataType,
        sizeof(sqlfpParameterDescription_T)); } else if (*funccode == 0) /*
        encode */ { memcpy((char *)argv[6], (char *)argv[4], 16);
        DESC((char*)argv[6], KEY, "0"); } else if (*funccode == 4) /* decode */
        { memcpy((char *)argv[4], (char *)argv[6], 16); memcpy((char *)argv[4],
        (char *)argv[6], 16); DESC((char *)argv[4], KEY, "1"); } else /*
        unsupported option -- error */ memcpy(sqlstate, "38003",5); }
Listagem 2. Esta amostra mostra como usar APIs do IBM i para criptografar e decriptografar. O programa poderia ser usado para criptografar e decriptografar um char, varchar ou clob de comprimento fixo.
 <!-- In this example,
        there are some points which need attention: --> <!-- a.
        The input/output data type could be a fixed char or varchar or clob.
        --> <!-- But the block size of the encryption should be
        16x(multiple time of 16).--> <!-- So, we should define
        enough space to store the encryption result. --> <!-- b.
        Avoid using pad option. Pad option will add a count of the pad
        characters --> <!-- in the end of original
        string.--> <!-- It may conduct one more block of the
        encryption result and the --> <!-- column does not have
        enough space to store. --> <!-- c. For better performance,
        ACTGRP(*CALLER), TERASPACE(*YES) and STGMDL(*INHERIT)-->
        <!-- were recommended when you compile your program.-->
        <!-- d. More information about IBM i Cryptographic Services APIs,
        --> <!-- please refer to the link of the IBM i infocenter
        below:--> <!--
        http://publib.boulder.ibm.com/infocenter/iseries/7.1m0/index.jsp
        --> #include <string.h> #include
        <stdlib.h> #include <stdio.h> #include
        <QC3CCI.H> #include <QUSEC.H> #include
        <QC3DTAEN.H> #include <QC3DTADE.H> #include
        <SQLFP.h> <!-- --------------------- -->
        <!-- SQL data type define. --> <!--
        --------------------- --> <!-- SQL data type CLOB
        --> #define SQL_CLOB_1 408 #define SQL_CLOB_2 409 <!-- SQL
        data type VARCHAR --> #define SQL_VARCHAR_1 448 #define
        SQL_VARCHAR_2 449 <!-- SQL data type CHAR --> #define
        SQL_CHAR_1 452 #define SQL_CHAR_2 453 <!--
        ------------------------------ --> <!-- Varlength SQL data
        type define. --> <!-- ------------------------------
        --> typedef _Packed struct { unsigned short int len; char
        data[512]; }T_VARCHAR; typedef _Packed struct { unsigned long len; char
        data[512]; }T_CLOB; Qc3_Format_ALGD0200_T *ALGD0200;
        Qc3_Format_KEYD0200_T *KEYD0200; Qus_EC_t ERRCODE; main(int argc, void
        *argv[]) { T_VARCHAR VarCharStr; T_CLOB ClobStr; short *funccode =
        argv[1]; sqlfpFieldProcedureParameterList_T *optionalParms = argv[2];
        char *sqlstate = argv[7]; sqlfpMessageText_T *msgtext = argv[8];
        sqlfpOptionalParameterValueDescriptor_T *optionalParmPtr; char
        Clear_Data[512]; char Encrypted_Data[512]; char Decrypted_Data[512]; int
        InputDataLen; int EncryptedDataLen; int DecryptedDataLen; int RtnLen;
        int i; char Qc3_Any_CSP_Flag = Qc3_Any_CSP; ALGD0200 =
        (Qc3_Format_ALGD0200_T *)malloc(sizeof(Qc3_Format_ALGD0200_T));
        ALGD0200->Block_Cipher_Alg = Qc3_AES;
        ALGD0200->Block_Length = 16; ALGD0200->Mode = Qc3_ECB;
        ALGD0200->Pad_Option = Qc3_No_Pad; ALGD0200->Pad_Character
        = '\x00' ; ALGD0200->MAC_Length = 0;
        ALGD0200->Effective_Key_Size = 0; ALGD0200->Reserved =
        '\x00'; memset(ALGD0200->Init_Vector,'\x00',32); KEYD0200 =
        (Qc3_Format_KEYD0200_T *)malloc(sizeof(Qc3_Format_KEYD0200_T) +16);
        KEYD0200->Key_Type = Qc3_AES ; KEYD0200->Key_String_Len =
        16; KEYD0200->Key_Format = Qc3_Bin_String; memcpy((char
        *)KEYD0200->Reserved + 3, "0123456789ABCDEF", 16); if (*funccode
        == 8) /* create time */ { sqlfpParameterDescription_T *inDataType =
        argv[3]; sqlfpParameterDescription_T *outDataType = argv[5]; /* do
        something here to determine the result data type */ /* ..... */ /* in
        this example input and output types are exactly the same */ /* so just
        copy */ memcpy(outDataType, inDataType,
        sizeof(sqlfpParameterDescription_T)); } else if (*funccode == 0) /*
        encode */ { sqlfpParameterDescription_T *inDataType = argv[3];
        InputDataLen = inDataType->sqlfpByteLength; if
        (inDataType->sqlfpSqlType == SQL_VARCHAR_1 ||
        inDataType->sqlfpSqlType == SQL_VARCHAR_2) { memcpy((char
        *)&VarCharStr, (char *)argv[4], InputDataLen+2); InputDataLen =
        VarCharStr.len; memcpy((char *)Clear_Data, (char *)VarCharStr.data,
        InputDataLen); if (InputDataLen % 16 > 0 || InputDataLen == 0) {
        memset((char *)Clear_Data + InputDataLen, '\x00', 16 - InputDataLen %
        16); InputDataLen = ((int)(InputDataLen / 16) + 1) * 16; } } else if
        (inDataType->sqlfpSqlType == SQL_CLOB_1 ||
        inDataType->sqlfpSqlType == SQL_CLOB_2) { memcpy((char
        *)&ClobStr, (char *)argv[4], InputDataLen+4); InputDataLen =
        ClobStr.len; memcpy((char *)Clear_Data, (char *)ClobStr.data,
        InputDataLen); if (InputDataLen % 16 > 0 || InputDataLen == 0) {
        memset((char *)Clear_Data + InputDataLen, '\x00', 16 - InputDataLen %
        16); InputDataLen = ((int)(InputDataLen / 16) + 1) * 16; } } else
        memcpy((char *)Clear_Data, (char *)argv[4], InputDataLen);
        memset(Encrypted_Data,'\x00',sizeof(Encrypted_Data)); EncryptedDataLen =
        sizeof(Encrypted_Data); Qc3EncryptData(Clear_Data,
        &InputDataLen, Qc3_Data, (char *)ALGD0200, Qc3_Alg_Block_Cipher,
        (char *)KEYD0200, Qc3_Key_Parms, &Qc3_Any_CSP_Flag, " ",
        Encrypted_Data, &amp;EncryptedDataLen, &RtnLen,
        &ERRCODE); if (inDataType->sqlfpSqlType == SQL_VARCHAR_1
        || inDataType->sqlfpSqlType == SQL_VARCHAR_2) { VarCharStr.len =
        RtnLen; memcpy((char *)VarCharStr.data, (char *)Encrypted_Data, RtnLen);
        memcpy((char *)argv[6], (char *)&VarCharStr, RtnLen+2); } else
        if (inDataType->sqlfpSqlType == SQL_CLOB_1 ||
        inDataType->sqlfpSqlType == SQL_CLOB_2) { ClobStr.len = RtnLen;
        memcpy((char *)ClobStr.data, (char *)Encrypted_Data, RtnLen);
        memcpy((char *)argv[6], (char *)&ClobStr, RtnLen+4); } else
        memcpy((char *)argv[6], (char *)Encrypted_Data, RtnLen); } else if
        (*funccode == 4) /* decodificar */ { sqlfpParameterDescription_T
        *inDataType = argv[3]; InputDataLen =
        inDataType->sqlfpByteLength; if (inDataType->sqlfpSqlType
        == SQL_VARCHAR_1 || inDataType->sqlfpSqlType == SQL_VARCHAR_2) {
        memcpy((char *)&VarCharStr, (char *)argv[6], InputDataLen+2);
        InputDataLen = VarCharStr.len; memcpy((char *)Encrypted_Data, (char
        *)VarCharStr.data, InputDataLen); } else if
        (inDataType->sqlfpSqlType == SQL_CLOB_1 ||
        inDataType->sqlfpSqlType == SQL_CLOB_2) { memcpy((char
        *)&ClobStr, (char *)argv[6], InputDataLen+4); InputDataLen =
        ClobStr.len; memcpy((char *)Encrypted_Data, (char *)ClobStr.data,
        InputDataLen); } else memcpy((char *)Encrypted_Data, (char *)argv[6],
        InputDataLen); memset(Decrypted_Data,'\x00',sizeof(Decrypted_Data));
        DecryptedDataLen = sizeof(Decrypted_Data);
        Qc3DecryptData(Encrypted_Data, &InputDataLen, (char *)ALGD0200,
        Qc3_Alg_Block_Cipher, (char *)KEYD0200, Qc3_Key_Parms,
        &Qc3_Any_CSP_Flag, " ", Decrypted_Data,
        &DecryptedDataLen, &RtnLen, &ERRCODE); if
        (inDataType->sqlfpSqlType == SQL_VARCHAR_1 ||
        inDataType->sqlfpSqlType == SQL_VARCHAR_2) { VarCharStr.len =
        strlen(Decrypted_Data); memcpy((char *)VarCharStr.data, (char
        *)Decrypted_Data, VarCharStr.len); memcpy((char *)argv[4], (char
        *)&VarCharStr, VarCharStr.len+2); } else if
        (inDataType->sqlfpSqlType == SQL_CLOB_1 ||
        inDataType->sqlfpSqlType == SQL_CLOB_2) { ClobStr.len =
        strlen(Decrypted_Data); memcpy((char *)ClobStr.data, (char
        *)Decrypted_Data, ClobStr.len); memcpy((char *)argv[4], (char
        *)&ClobStr, ClobStr.len+4); } else memcpy((char *)argv[4], (char
        *)Decrypted_Data, RtnLen); } else /* unsupported option -- error */
        memcpy(sqlstate, "38003",5); }
Listagem 3. Esta amostra é um exemplo de versão de código RPG para FieldProc. Ela reverte os caracteres de uma coluna lob ou varchar como o método de criptografia.
 D FuncCode S 2B 0 D p_FuncCode S * D OptParms
        DS LikeDs(SQLFOPVD) D* D EnCodTyp DS LikeDs(SQLFPD) D* D DeCodTyp DS
        LikeDs(SQLFPD) D* D EnCodDta S 512 D DeCodDta S 512 D* D SqlState S 5 D
        SqMsgTxt DS LikeDs(SQLFMT) D* D En_Lob_Ds Ds Qualified D Len 5B 0 D Data
        1 dim(512) D D De_Lob_Ds Ds LikeDs(En_Lob_Ds) D D En_VChar_Ds Ds
        Qualified D Len 2B 0 D Data 1 dim(512) D D De_VChar_Ds Ds
        LikeDs(En_VChar_Ds) D D i S 10I 0 D /COPY QSYSINC/QRPGLESRC,SQLFP C
        *Entry Plist C Parm FuncCode C Parm OptParms C Parm DeCodTyp C Parm
        DeCodDta C Parm EnCodTyp C Parm EnCodDta C Parm SqlState C Parm SqMsgTxt
        /Free If FuncCode = 8 ; // do something here to determine the result
        data type // ..... // in this example input and output types are exactly
        the same // so just copy EnCodTyp = DeCodTyp ; ElseIf FuncCode = 0 ; //
        encode If DeCodTyp.SQLFST = 408 or DeCodTyp.SQLFST = 409 ; // clob // in
        this example, reverse the characters as encryption De_Lob_Ds = DeCodDta
        ; En_Lob_Ds.Len = De_Lob_Ds.Len ; i = De_Lob_Ds.Len ; DoW i > 0 ;
        En_Lob_Ds.Data(De_Lob_Ds.Len-i+1) = De_Lob_Ds.Data(i) ; i = i - 1 ;
        EndDo ; EnCodDta = En_Lob_Ds ; ElseIf DeCodTyp.SQLFST = 448 or
        DeCodTyp.SQLFST = 449 ; // varchar // in this example, reverse the
        characters as encryption De_VChar_Ds = DeCodDta ; En_VChar_Ds.Len =
        De_VChar_Ds.Len ; i = De_VChar_Ds.Len ; DoW i > 0 ;
        En_VChar_Ds.Data(De_VChar_Ds.Len-i+1) = De_VChar_Ds.Data(i) ; i = i - 1
        ; EndDo ; EnCodDta = En_VChar_Ds ; Else ; // other data type, just put
        the same value. EnCodDta = DeCodDta ; EndIf ; SqlState = '00000' ;
        ElseIf FuncCode = 4 ; // decode If EnCodTyp.SQLFST = 408 or
        EnCodTyp.SQLFST = 409 ; // clob // in this example, reverse the
        characters as decryption En_Lob_Ds = EnCodDta ; De_Lob_Ds.Len =
        En_Lob_Ds.Len ; i = En_Lob_Ds.Len ; DoW i > 0 ;
        De_Lob_Ds.Data(En_Lob_Ds.Len-i+1) = En_Lob_Ds.Data(i) ; i = i - 1 ;
        EndDo ; DeCodDta = De_Lob_Ds ; ElseIf EnCodTyp.SQLFST = 448 or
        EnCodTyp.SQLFST = 449 ; // varchar En_VChar_Ds = EnCodDta ;
        De_VChar_Ds.Len = En_VChar_Ds.Len ; i = En_VChar_Ds.Len ; DoW i >
        0 ; De_VChar_Ds.Data(En_VChar_Ds.Len-i+1) = En_VChar_Ds.Data(i) ; i = i
        - 1 ; EndDo ; DeCodDta = De_VChar_Ds ; Else ; // other data type, just
        put the same value. DeCodDta = EnCodDta ; EndIf ; SqlState = '00000' ;
        Else ; SqlState = '38003' ; EndIf ; *InLR = *On ; Return ; /End-Free

Considerações Especiais ao Usar o FieldProc

Há diversas diretrizes que devem ser levadas em consideração ao adotar o suporte ao procedimento de campo. Os itens chave incluem:

  • O procedimento de campo deve ser um objeto ILE *PGM. Observe que objetos *SRVPGMs, OPM *PGMs e JAVA não são suportados.
  • Nenhum SQL é permitido em um procedimento de campo.
  • O procedimento de campo deve ser determinista. É muito perigoso usar procedimentos de campo que não são deterministas, pois os dados codificados podem não ser capazes de decodificar de volta para seu valor original.
  • Quando o comando Change Physical File (CHGPF) é usado com o parâmetro SRCFILE para alterar a definição de campo de um arquivo físico, o comando CHGPF removerá todos os procedimentos de Campo registrados nesse arquivo físico sem qualquer mensagem de aviso.

Para restrições adicionais, consulte a referência de SQL para obter detalhes.

Conclusão

Este artigo forneceu uma visão rápida dos recursos que estão disponíveis por meio do suporte ao procedimento de campo no IBM i 7.1. Com a utilização do suporte ao procedimento de campo, é possível executar facilmente uma criptografia transparente no nível da coluna dos dados armazenados em um banco de dados. Você pode usar FieldProc para qualquer tipo de esquema de codificação - ele não está limitado à criptografia.

Há vários métodos de criptografia que podem ser escolhidos. Por exemplo, FieldProc de AES, ou DES triplo e outros são comumente usados. É claro que também é possível usar um produto de criptografia de terceiros, como Linoma, Patrick Townsend e nuBridges, como uma solução fácil e completa. Mas ao implementar aplicativos do IBM i, o suporte ao procedimento de campo é uma forte solução de criptografia de dados.

Agradecimento

Agradecemos muito a nossos especialistas de Rochester que ajudaram a revisar o artigo. Um agradecimento especial a Kent Milligan que forneceu muitos comentários valiosos.

Recursos

Aprender

Obter produtos e tecnologias

Discutir

Comentários

developerWorks: Conecte-se

Los campos obligatorios están marcados con un asterisco (*).


Precisa de um ID IBM?
Esqueceu seu ID IBM?


Esqueceu sua senha?
Alterar sua senha

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

 


A primeira vez que você entrar no developerWorks, um perfil é criado para você. Informações no seu perfil (seu nome, país / região, e nome da empresa) é apresentado ao público e vai acompanhar qualquer conteúdo que você postar, a menos que você opte por esconder o nome da empresa. Você pode atualizar sua conta IBM a qualquer momento.

Todas as informações enviadas são seguras.

Elija su nombre para mostrar



Ao se conectar ao developerWorks pela primeira vez, é criado um perfil para você e é necessário selecionar um nome de exibição. O nome de exibição acompanhará o conteúdo que você postar no developerWorks.

Escolha um nome de exibição de 3 - 31 caracteres. Seu nome de exibição deve ser exclusivo na comunidade do developerWorks e não deve ser o seu endereço de email por motivo de privacidade.

Los campos obligatorios están marcados con un asterisco (*).

(Escolha um nome de exibição de 3 - 31 caracteres.)

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

 


Todas as informações enviadas são seguras.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=80
Zone=Information Management
ArticleID=620478
ArticleTitle=Aprimoramentos de Criptografia: Suporte a Procedimento de Campo no DB2 para i 7.1
publish-date=01272011