3.2 Sintaxe
3.2.2 Elemento EncryptionMethod
O elemento EncryptionMethod é um elemento opcional que define o algoritmo aplicado aos dados cifrados. Se este elemento estiver ausente, o algoritmo deverá ser conhecido pelo destinatário da mensagem.
J S O N S c h e m a D e f i n i t i o n :
Requisitos
" $ s c h e m a " : " h t t p :// json - s c h e m a . org / draft - 0 4 / s c h e m a # " ,
" t i t l e " : " E n c r y p t i o n M e t h o d " , " t y p e " : " o b j e c t " , " p r o p e r t i e s " :{ " A l g o r i t h m " :{ " t y p e " : " s t r i n g " } , " K e y S i z e " :{ " t y p e " : " i n t e g e r " } , " O A E P p a r a m s " :{ " t y p e " : " s t r i n g " } } , " r e q u i r e d " :[ " A l g o r i t h m " ] }
Código Fonte 3.2: Elemento EncryptionMethod
3.2.3
Elemento CipherData
O elemento CipherData contém os dados cifrados. Este elemento deve ainda con- ter o conteúdo do elemento CipherValue cifrado e codificado numa sequência em formato Base64.
J S O N S c h e m a D e f i n i t i o n :
{
" $ s c h e m a " : " h t t p :// json - s c h e m a . org / draft - 0 4 / s c h e m a # " , " t i t l e " : " C i p h e r D a t a " , " t y p e " : " o b j e c t " , " p r o p e r t i e s " :{ " C i p h e r V a l u e " :{ " p r o p e r t i e s " :{ " C i p h e r V a l u e " :{ " t y p e " : " s t r i n g " } } , " r e q u i r e d " :[ " C i p h e r V a l u e " ] } 40
Requisitos
}
}
Código Fonte 3.3: Elemento CipherData
3.2.3.1 Elemento CipherReference
Caso o conteúdo do elemento CipherValue não seja fornecido diretamente, o ele- mento CipherReference identifica uma fonte que quando processada, produz a sequência de octetos cifrada.
A obtenção do valor real ocorre através do identificador presente no CipherRe- ference URI, cujo valor funciona como referência para a fonte. Caso o elemento possua uma sequência de transformações (elemento Transforms), os dados obtidos na fonte são transformados de acordo com a especificação, obtendo-se assim a cifra pretendida.
J S O N S c h e m a D e f i n i t i o n :
{
" $ s c h e m a " : " h t t p :// json - s c h e m a . org / draft - 0 4 / s c h e m a # " ,
" t i t l e " : " C i p h e r R e f e r e n c e " , " t y p e " : " o b j e c t " , " p r o p e r t i e s " :{ " URI " :{ " t y p e " : " s t r i n g " } , " T r a n s f o r m s " :{ " t y p e " : " o b j e c t " , " p r o p e r t i e s " :{ " T r a n s f o r m " :{ " t y p e " : " o b j e c t " , " p r o p e r t i e s " :{ " A l g o r i t h m " :{ " t y p e " : " s t r i n g " } } , " r e q u i r e d " :[ " A l g o r i t h m " ] } , " A l g o r i t h m " :{
Requisitos " t y p e " : " s t r i n g " } } , " r e q u i r e d " :[ " A l g o r i t h m " ] } } , " r e q u i r e d " :[ " URI " ] }
Código Fonte 3.4: Elemento CipherReference
3.2.4
Elemento EncryptedData
O EncryptedData é o elemento principal da sintaxe, que deriva do elemento En- cryptedType. Este elemento substitui o elemento cifrado.
J S O N S c h e m a D e f i n i t i o n :
{
" $ s c h e m a " : " h t t p :// json - s c h e m a . org / draft - 0 4 / s c h e m a # " , " t i t l e " : " E n c r y p t e d D a t a " , " t y p e " : " o b j e c t " , " p r o p e r t i e s " :{ " E n c r y p t i o n M e t h o d " :{ " $ r e f " : " #/ d e f i n i t i o n s / E n c r y p t i o n M e t h o d " } , " K e y I n f o " :{ " $ r e f " : " #/ d e f i n i t i o n s / K e y I n f o " } , " C i p h e r D a t a " :{ " $ r e f " : " #/ d e f i n i t i o n s / C i p h e r D a t a " } } , " r e q u i r e d " :[ " E n c r y p t i o n M e t h o d " , " K e y I n f o " , " C i p h e r D a t a " ] , " a d d i t i o n a l P r o p e r t i e s " : f a l s e } 42
Requisitos
Código Fonte 3.5: Elemento EncryptedData
3.2.5
Elemento KeyInfo
Existem duas maneiras de fornecer a informação relativa a chaves criptográficas necessárias para decifrar o CipherData:
• Os elementos EncryptedData ou EncryptedKey especificam o material rela- tivo à chave de criptografia através de um elemento filho de KeyInfo.
• O material relativo à chave criptográfico pode ser determinada, implicita- mente pelo destinatário, desta forma não precisa ser explicitamente mencio- nado no JSON transmitido.
J S O N S c h e m a D e f i n i t i o n :
{
" $ s c h e m a " : " h t t p :// json - s c h e m a . org / draft - 0 4 / s c h e m a # " , " t i t l e " : " K e y I n f o " , " t y p e " : " o b j e c t " , " o n e O f " :[ { " t y p e " : " o b j e c t " , " p r o p e r t i e s " :{ " E n c r y p t e d K e y " :{ " $ r e f " : " #/ d e f i n i t i o n s / E n c r y p t e d K e y " } } , " r e q u i r e d " :[ " E n c r y p t e d K e y " ] } , { " t y p e " : " o b j e c t " , " p r o p e r t i e s " :{ " R e t r i e v a l M e t h o d " :{ " $ r e f " : " #/ d e f i n i t i o n s / R e t r i e v a l M e t h o d " } } ,
Requisitos " r e q u i r e d " :[ " R e t r i e v a l M e t h o d " ] } ] }
Código Fonte 3.6: Elemento KeyInfo
3.2.5.1 Elemento EncryptedKey
O elemento EncryptedKey é utilizado para transportar a chave de encriptação desde o emissor até aos receptores conhecidos. A chave é sempre cifrada para os destinatários. Quando este elemento é decifrado, os octetos resultantes são colo- cados à disposição do algoritmo EncryptionMethod sem processamento adicional.
J S O N S c h e m a D e f i n i t i o n :
{
" $ s c h e m a " : " h t t p :// json - s c h e m a . org / draft - 0 4 / s c h e m a # " , " t i t l e " : " E n c r y p t e d K e y " , " t y p e " : " o b j e c t " , " p r o p e r t i e s " :{ " E n c r y p t i o n M e t h o d " :{ " $ r e f " : " #/ d e f i n i t i o n s / E n c r y p t i o n M e t h o d " } , " K e y I n f o " :{ " $ r e f " : " #/ d e f i n i t i o n s / K e y I n f o " } , " C i p h e r D a t a " :{ " $ r e f " : " #/ d e f i n i t i o n s / C i p h e r D a t a " } } , " r e q u i r e d " :[ " E n c r y p t i o n M e t h o d " , " K e y I n f o " , " C i p h e r D a t a " ] }
Código Fonte 3.7: Elemento EncryptedKey
Requisitos
3.2.5.2 Elemento RetrievalMethod
O elemento RetrievalMethod identifica um elemento EncryptedKey que contém a chave necessária para decifrar o elemento CipherData associado.
J S O N S c h e m a D e f i n i t i o n :
{
" $ s c h e m a " : " h t t p :// json - s c h e m a . org / draft - 0 4 / s c h e m a # " , " t i t l e " : " R e t r i e v a l M e t h o d " ,
" t y p e " : " s t r i n g "
}
Código Fonte 3.8: Elemento RetrievalMethod
3.2.6
Regras de Processamento
Esta secção descreve as operações de processamento criptográfico, os momentos em que a informação é cifrada/decifrada e os elementos utilizados. Os perfis seguintes foram definidos como requisitos de conformidade:
• Aplicação
Aplicação que efetua o pedido a uma implementação SecJSON através de dados e parâmetros necessários para o seu processamento.
• Encryptor
Implementação SecJSON com perfil de cifra de informação.
• Decryptor
Implementação SecJSON com perfil de decifra de informação.
3.2.6.1 Cifra
Para cifrar um conjunto de informação como um elemento EncryptedData ou En- cryptedKey (elementos derivados de EncryptedType) o Encryptor deve:
Requisitos
1. Seleccionar o algoritmo e parâmetros necessários para a cifra dos dados.
2. Obter e (opcionalmente) representar a chave.
(a) A chave em si poderá ser cifrada em conjunto com a informação. Para isso deverá ser construido um elemento EncryptedKey através da apli- cação deste processo de forma recursiva. O elemento EncryptedKey resultante será um filho do elemento KeyInfo.
3. Cifrar os dados:
(a) Obter os octetos através da serialização dos dados em UTF-8 (ou outro enconding escolhido pela Aplicação). A serialização pode ser feita pelo Encryptor , caso contrário a mesma deverá ser feita pela Aplicação.
(b) Cifrar octetos através da utilização do algoritmo e chave obtidos nos passos 1 e 2.
(c) Com excepção do Decryptor ter conhecimento do tipo de dados sujei- tos ao processo de cifra, o Encryptor deverá fornecer esta informação.
4. Construir a estrutra EncryptedType (EncryptedData ou EncryptedKey):
A estrutura EncryptedType representa todas as informações préviamente dis- cutidas, incluindo o algoritmo de criptografia, parâmetros, chave, dados ci- frados, etc.
(a) Caso seja necessário armazenar a sequência de octetos obtida no passo 3 (CipherData), a sequência é codificada em formato Base64 e inserida como conteúdo de um elemento CipherValue.
(b) Caso seja necessário armazenar externamente a sequência de octetos, a representação do URI e transformações (caso existam) correspondente à localização da sequência cifrada será armazenada dentro do elemento CipherReference.
5. Processar EncryptedData:
Requisitos
(a) Caso o tipo de dados cifrados seja um elemento JSON o Encryptor deve permitir o retorno do elemento EncryptedData para a Aplicação. Esta poderá usar o elemento como um novo documento JSON ou inserir o mesmo noutro documento JSON.
O Encryptor deve permitir a substituição do elemento não cifrado pelo elemento EncryptedData. Quando a Aplicação requer um ele- mento JSON para substituição, fornece o contexto do documento JSON e identifica o elemento a ser substituído. O Encryptor remove o ele- mento e insere o elemento EncryptedData respetivo.
(b) Caso o tipo de dados cifrados não seja um elemento JSON, o Encryptor deve retornar sempre o elemento EncryptedData para a Aplicação. Esta poderá usar o elemento como um novo documento JSON ou inserir o mesmo noutro documento JSON.
Figura 3.3: Processo de cifra SecJSON
3.2.6.2 Decifra
Para cada elemento, derivado de EncryptedType, a decifrar, o Decryptor deve:
1. Processar o elemento e determinar o algoritmo, parâmetro e elemento KeyInfo a utilizar. Caso alguma informação esteja omitida, a Aplicação é respon- sávels pelo seu fornecimento.
Requisitos
2. Identificar a chave criptográfica de acordo com o elemento KeyInfo. No caso de a chave se encontrar cifrada, deverá ser identificada a chave correspon- dente, posteriormente deverá ser realizado o processo de decifrar de modo recursivo. Caso contrário, a chave criptográfica poderá ser obtida através de uma local store utilizando os parâmetros fornecidos ou vínculo implícito.
3. Decifrar os dados contidos no elemento CipherData:
(a) Caso o elemento CipherValue esteja presente, o contúdo será sujeito a uma descodificação Base64 obtendo a sequência de octetos cifrada.
(b) Caso o elemento CipherReference esteja presente, o URI e transfor- mações (caso existam) são usadas para obter a sequência de octetos cifrada.
(c) A sequência de octetos cifrada é decifrada utilizando o algoritmo/parâ- metros e chave determinados nos passos 1 e 2.
4. Processar dados decifrados
(a) O sequência de octetos obtida no passo 3 é interpretado com o encoding UTF-8.
(b) O Decryptor deve permitir o retorno dos dados numa estrutura JSON com o encoding definido. O Decryptor não é obrigado a validar o JSON serializado.
(c) O Decryptor deve suportar a capacidade de substituir o elemento EncryptedData pelo elemento JSON decifrado ou conteúdo simples. O Decryptor não é obrigado a validar o resultado desta operação de substituição.
A Aplicação fornece o contexto do documento JSON e identifica o elemento EncryptedData a substítuir. Se o documento alvo não possuir o encoding UTF-8, o Decryptor deve efetuar a codificação para o encoding correto.
Requisitos
Figura 3.4: Processo de decifra SecJSON
3.2.7
Algoritmos
Esta secção discute os algoritmos utilizados com a especificação SecJSON. O con- teúdo do Algorithm do elemento EncryptionMethod é o identificador do algoritmo (secção 3.2.7) ou outro elemento representativo do papel do algoritmo, uma refe- rência formal para uma especificação, definição da chave criptográfica e resultados das operações de criptografia aplicadas.
O conjunto de algoritmos listados abaixo têm parâmetros implícitos que de- pendem do seu papel (dados para cifra/decifra, materiais relativos a chave ou a operação criptográfica a executar). Quaisquer parâmetros adicionais explícitos surgem como elementos filho do elemento EncryptionMethod.
Lista de Algoritmos por Categoria
Foram definidos um conjunto de algoritmos obrigatórios (e recomendados) para as categorias Block Encryption, Key Transport e Message Digest. Desta forma, qual- quer implementação do mecanismo SecJSON permitirá, no minimo, a utilização dos algoritmos definidos como obrigatórios.
Em cada categoria existe um nome breve, nível de exigência da implementação e um URI de identificação de cada algoritmo.
Requisitos Block Encryption 1. OBRIGATÓRIO - TRIPLEDES http://tiagomistral.github.io/SecJSON#tripledes-cbc 2. OBRIGATÓRIO - AES-128 http://tiagomistral.github.io/SecJSON#aes128-cbc 3. RECOMENDADO - AES-192 http://tiagomistral.github.io/SecJSON#aes192-cbc 4. OBRIGATÓRIO - AES-256 http://tiagomistral.github.io/SecJSON#aes256-cbc Key Transport 1. OBRIGATÓRIO - RSA-v1.5 http://tiagomistral.github.io/SecJSON#rsa-1_5 2. OBRIGATÓRIO - RSA-OAEP http://tiagomistral.github.io/SecJSON#rsa-oaep-mgf1p Message Digest 1. OBRIGATÓRIO - SHA1 http://tiagomistral.github.io/SecJSON#sha1
Conclusões
Após a definição desta sintaxe é possível implementar, utilizando todas as regras e restrições anteriores. um sistema que permite cifrar e decifrar qualquer tipo de dados num objeto SecJSON. Caso os dados a cifrar já se encontrem no formato JSON, será ainda possível aplicar várias cifras diferentes sobre objetos diferentes dentro do mesmo documento JSON.
Requisitos
No próximo capitulo será desenvolvido um protótipo deste sistema numa das linguagens analisadas na seção 2.5.
Capítulo 4
Implementação do Sistema
Ao longo deste capítulo será definido e apresentado um ambiente para a implemen- tação da especificação SecJSON definida e proposta anteriormente. Este capítulo está dividido em três secções que apresentam e justificam a fase de implementa- ção e utilização do SecJSON. Desta forma, para alcançar os objetivos definidos a implementação de uma solução do mecanismo SecJSON foi divido nas três fases que se apresentam de seguida.
1. Definição de um ambiente de implementação onde será escolhida uma lin- guagem de programação que satisfaça todos os requisitos definidos anterior- mente.
2. Implementação e disponibilização da solução na linguagem definida.
3. Exemplos de utilização da solução desenvolvida.
No final deste capítulo será possível para qualquer pessoa incorporar o meca- nismo de segurança SecJSON nas suas próprias aplicações e serviços.
Implementação do Sistema
4.1
Ambiente de Desenvolvimento
Para a implementação e validação de uma solução deste mecanismo de segurança foi usada a framework Node.js. Além de todas as vantagens enumeradas ante- riormente na secção 2.5.3 e do gestor de pacotes NPM, o Node.js é baseado em JavaScript tal como o formato JSON. Esta base comum apresenta-se como um trunfo importante ao nível da performance e aprendizagem inerente ao desenvol- vimento deste trabalho.
4.2
Arquitectura
A arquitectura do sistema será divida em três módulos distintos (Figura 4.1):
• Módulo de obtenção dos dados a cifrar/decifrar
Módulo é responsável por receber da aplicação/serviço cliente a informação necessária para as operações criptográficas e invocação do módulo cifra/de- cifra.
• Módulo de cifra
Módulo que agrega todas as funções criptográficas relativas à cifra da infor- mação e construção da estrutura SecJSON resultante.
• Módulo de decifra
Contrariamente ao módulo de cifra, o módulo de decifra agrega todas as funções criptográficas relativas à decifra da estrutura SecJSON e construção do objeto JSON resultante.
Implementação do Sistema
Figura 4.1: Arquitectura SecJSON
4.3
secjson.js
Durante esta secção serão apresentadas as principais funções Node.js desenvolvidas de acordo com a sintaxe definida nas secções anteriores.
4.3.1
Processo de cifra
O processo de cifra (função encrypt - código fonte 4.1) é responsável por receber um conteúdo a cifrar e devolver um objeto JSON de acordo com a sintaxe definida. Como parâmetros obrigatórios esta função exige:
• Conteúdo a cifrar;
• Uma chave pública RSA;
• Um certificado x509 em formato PEM.
Posteriormente serão invocados, de forma sequencial, os métodos necessários à cifra do conteúdo fornecido:
1. generate_symmetric_key
Gerar uma chave simétrica para cifrar o conteúdo definido pelo utilizador.
Implementação do Sistema
Cifrar o conteúdo definido pelo utilizador com a chave gerada no ponto an- terior.
3. encrypt_key
Cifrar a chave simétrica utilizada na criptografia com a chave publica forne- cida pelo utilizador.
(a) utils.renderTemplate
Gerar o objeto JSON com a informação criptográfica nos elementos SecJSON correspondentes. f u n c t i o n e n c r y p t ( content , options , c a l l b a c k ) { if (! o p t i o n s ) r e t u r n c a l l b a c k ( new E r r o r ( ’ m u s t p r o v i d e o p t i o n s ’ )); if (! c o n t e n t ) r e t u r n c a l l b a c k ( new E r r o r ( ’ m u s t p r o v i d e c o n t e n t to e n c r y p t ’ )); if (! o p t i o n s . r s a _ p u b )
r e t u r n c a l l b a c k ( new E r r o r ( ’ r s a _ p u b o p t i o n is m a n d a t o r y and you s h o u l d p r o v i d e a v a l i d RSA p u b l i c key ’ ));
if (! o p t i o n s . pem )
r e t u r n c a l l b a c k ( new E r r o r ( ’ pem o p t i o n is m a n d a t o r y and you s h o u l d p r o v i d e a
v a l i d x 5 0 9 c e r t i f i c a t e e n c o d e d as PEM ’ )); o p t i o n s . i n p u t _ e n c o d i n g = o p t i o n s . i n p u t _ e n c o d i n g || ’ u t f 8 ’ ; a s y n c . w a t e r f a l l ([ f u n c t i o n g e n e r a t e _ s y m m e t r i c _ k e y ( cb ) { s w i t c h ( o p t i o n s . e n c r y p t i o n A l g o r i t h m ) { c a s e ’ h t t p :// t i a g o m i s t r a l . g i t h u b . io / S e c J S O N # aes128 - cbc ’ : c r y p t o . r a n d o m B y t e s (16 , cb ); // g e n e r a t e a s y m m e t r i c r a n d o m key 16 b y t e s // l e n g t h b r e a k ; c a s e ’ h t t p :// t i a g o m i s t r a l . g i t h u b . io / S e c J S O N # aes256 - cbc ’ : c r y p t o . r a n d o m B y t e s (32 , cb ); // g e n e r a t e a s y m m e t r i c r a n d o m key 32 b y t e s // l e n g t h b r e a k ; c a s e ’ h t t p :// t i a g o m i s t r a l . g i t h u b . io / S e c J S O N # t r i p l e d e s - cbc ’ : c r y p t o . r a n d o m B y t e s (24 , cb ); // g e n e r a t e a s y m m e t r i c r a n d o m key 24 b y t e s // ( 1 9 2 b i t s ) l e n g t h b r e a k ; d e f a u l t : c r y p t o . r a n d o m B y t e s (32 , cb ); // g e n e r a t e a s y m m e t r i c r a n d o m key 32 b y t e s // l e n g t h } 56
Implementação do Sistema } , f u n c t i o n e n c r y p t _ c o n t e n t ( s y m m e t r i c K e y , cb ) { s w i t c h ( o p t i o n s . e n c r y p t i o n A l g o r i t h m ) { c a s e ’ h t t p :// t i a g o m i s t r a l . g i t h u b . io / S e c J S O N # aes128 - cbc ’ : e n c r y p t W i t h A l g o r i t h m ( ’ aes -128 - cbc ’ , s y m m e t r i c K e y , 16 , content , o p t i o n s . i n p u t _ e n c o d i n g , f u n c t i o n ( err , e n c r y p t e d C o n t e n t ) { if ( err ) r e t u r n cb ( err ); cb ( null , s y m m e t r i c K e y , e n c r y p t e d C o n t e n t ); }); b r e a k ; c a s e ’ h t t p :// t i a g o m i s t r a l . g i t h u b . io / S e c J S O N # aes256 - cbc ’ : e n c r y p t W i t h A l g o r i t h m ( ’ aes -256 - cbc ’ , s y m m e t r i c K e y , 16 , content , o p t i o n s . i n p u t _ e n c o d i n g , f u n c t i o n ( err , e n c r y p t e d C o n t e n t ) { if ( err ) r e t u r n cb ( err ); cb ( null , s y m m e t r i c K e y , e n c r y p t e d C o n t e n t ); }); b r e a k ; c a s e ’ h t t p :// t i a g o m i s t r a l . g i t h u b . io / S e c J S O N # t r i p l e d e s - cbc ’ :
e n c r y p t W i t h A l g o r i t h m ( ’ des - ede3 - cbc ’ , s y m m e t r i c K e y , 8 , content , o p t i o n s . i n p u t _ e n c o d i n g , f u n c t i o n ( err , e n c r y p t e d C o n t e n t ) { if ( err ) r e t u r n cb ( err ); cb ( null , s y m m e t r i c K e y , e n c r y p t e d C o n t e n t ); }); b r e a k ; d e f a u l t : cb ( new E r r o r ( ’ e n c r y p t i o n a l g o r i t h m not s u p p o r t e d ’ )); } } , f u n c t i o n e n c r y p t _ k e y ( s y m m e t r i c K e y , e n c r y p t e d C o n t e n t , cb ) { e n c r y p t K e y I n f o ( s y m m e t r i c K e y , options , f u n c t i o n ( err , k e y I n f o ) { if ( err ) r e t u r n cb ( err ); var r e s u l t = u t i l s . r e n d e r T e m p l a t e ( ’ e n c r y p t e d - key ’ , { e n c r y p t e d C o n t e n t : e n c r y p t e d C o n t e n t . t o S t r i n g ( ’ b a s e 6 4 ’ ) , k e y I n f o : keyInfo , c o n t e n t E n c r y p t i o n M e t h o d : o p t i o n s . e n c r y p t i o n A l g o r i t h m }); cb ( null , r e s u l t ); }); } ] , c a l l b a c k ); }
Implementação do Sistema
4.3.2
Processo de decifra
O processo de decifra (função decrypt - código fonte 4.2) é responsável por receber um objeto JSON de acordo com a sintaxe SecJSON e uma chave privada e devolver o conteúdo decifrado. Como parâmetros obrigatórios esta função exige:
• Objeto JSON de acordo com a sintaxe SecJSON; • Uma chave privada RSA.
Posteriormente serão invocados, de forma sequencial, os métodos necessários à cifra do conteúdo fornecido:
1. JSON.parse
Validar objeto JSON fornecido.
2. decryptKeyInfo
Decifrar o conteúdo do elemento EncryptedData.KeyInfo.CipherData com a chave privada fornecida, obtendo a chave simétrica utilizada no processo de cifra do payload.
3. switch (encryptionAlgorithm)
Decifrar o payload com a chave simétrica obtida no ponto anterior. Este pro- cesso está dependente do elemento EncryptedData.EncryptionMethod, cuja informação corresponde ao algoritmo criptográfico utilizado (AES 128, AES 256 ou TripleDES). f u n c t i o n d e c r y p t ( json , options , c a l l b a c k ) { if (! o p t i o n s ) r e t u r n c a l l b a c k ( new E r r o r ( ’ m u s t p r o v i d e o p t i o n s ’ )); if (! j s o n ) r e t u r n c a l l b a c k ( new E r r o r ( ’ m u s t p r o v i d e J S O N to d e c r y p t ’ )); if (! o p t i o n s . key )
r e t u r n c a l l b a c k ( new E r r o r ( ’ key o p t i o n is m a n d a t o r y and you s h o u l d p r o v i d e a v a l i d RSA p r i v a t e key ’ ));
var d e c r y p t e d ;
Implementação do Sistema try { var doc = J S O N . p a r s e ( j s o n ); var s y m m e t r i c K e y = d e c r y p t K e y I n f o ( doc , o p t i o n s ); var e n c r y p t i o n A l g o r i t h m = doc . E n c r y p t e d D a t a . E n c r y p t i o n M e t h o d . A l g o r i t h m ; var d e c i p h e r ; var p a d d i n g ; var e n c r y p t e d C o n t e n t = doc . E n c r y p t e d D a t a . C i p h e r D a t a . C i p h e r V a l u e ; var e n c r y p t e d = new B u f f e r ( e n c r y p t e d C o n t e n t , ’ b a s e 6 4 ’ ); s w i t c h ( e n c r y p t i o n A l g o r i t h m ) { c a s e ’ h t t p :// t i a g o m i s t r a l . g i t h u b . io / S e c J S O N # aes128 - cbc ’ : d e c i p h e r = c r y p t o . c r e a t e D e c i p h e r i v ( ’ aes -128 - cbc ’ , s y m m e t r i c K e y , e n c r y p t e d . s l i c e (0 , 1 6 ) ) ; d e c i p h e r . s e t A u t o P a d d i n g ( f a l s e ); d e c r y p t e d = d e c i p h e r . u p d a t e ( e n c r y p t e d . s l i c e (16) , null , ’ b i n a r y ’ ) + d e c i p h e r . f i n a l ( ’ b i n a r y ’ );
// R e m o v e p a d d i n g b y t e s e q u a l to the v a l u e of the l a s t b y t e of the r e t u r n e d d a t a . p a d d i n g = d e c r y p t e d . c h a r C o d e A t ( d e c r y p t e d . l e n g t h - 1); if (1 <= p a d d i n g && p a d d i n g <= 16) { d e c r y p t e d = d e c r y p t e d . s u b s t r (0 , d e c r y p t e d . l e n g t h - p a d d i n g ); } e l s e { c a l l b a c k ( new E r r o r ( ’ p a d d i n g l e n g t h i n v a l i d ’ )); r e t u r n ; } d e c r y p t e d = new B u f f e r ( d e c r y p t e d , ’ b i n a r y ’ ). t o S t r i n g ( ’ u t f 8 ’ ); b r e a k ; c a s e ’ h t t p :// t i a g o m i s t r a l . g i t h u b . io / S e c J S O N # aes256 - cbc ’ : d e c i p h e r = c r y p t o . c r e a t e D e c i p h e r i v ( ’ aes -256 - cbc ’ , s y m m e t r i c K e y , e n c r y p t e d . s l i c e (0 , 1 6 ) ) ; d e c i p h e r . s e t A u t o P a d d i n g ( f a l s e ); d e c r y p t e d = d e c i p h e r . u p d a t e ( e n c r y p t e d . s l i c e (16) , null , ’ b i n a r y ’ ) + d e c i p h e r . f i n a l ( ’ b i n a r y ’ );
// R e m o v e p a d d i n g b y t e s e q u a l to the v a l u e of the l a s t b y t e of the r e t u r n e d d a t a .
p a d d i n g = d e c r y p t e d . c h a r C o d e A t ( d e c r y p t e d . l e n g t h - 1); if (1 <= p a d d i n g && p a d d i n g <= 16) { d e c r y p t e d = d e c r y p t e d . s u b s t r (0 , d e c r y p t e d . l e n g t h - p a d d i n g ); } e l s e { c a l l b a c k ( new E r r o r ( ’ p a d d i n g l e n g t h i n v a l i d ’ )); r e t u r n ;
Implementação do Sistema } d e c r y p t e d = new B u f f e r ( d e c r y p t e d , ’ b i n a r y ’ ). t o S t r i n g ( ’ u t f 8 ’ ); b r e a k ; c a s e ’ h t t p :// t i a g o m i s t r a l . g i t h u b . io / S e c J S O N # t r i p l e d e s - cbc ’ : d e c i p h e r = c r y p t o . c r e a t e D e c i p h e r i v ( ’ des - ede3 - cbc ’ , s y m m e t r i c K e y , e n c r y p t e d . s l i c e (0 ,8)); d e c r y p t e d = d e c i p h e r . u p d a t e ( e n c r y p t e d . s l i c e (8) , null , ’ b i n a r y ’ ) + d e c i p h e r . f i n a l ( ’ b i n a r y ’ ); d e c r y p t e d = new B u f f e r ( d e c r y p t e d , ’ b i n a r y ’ ). t o S t r i n g ( ’ u t f 8 ’ ); b r e a k ; d e f a u l t : r e t u r n c a l l b a c k ( new E r r o r ( ’ e n c r y p t i o n a l g o r i t h m ’ + e n c r y p t i o n A l g o r i t h m + ’ not s u p p o r t e d ’ )); } } c a t c h ( e ) { r e t u r n c a l l b a c k ( e ); } c a l l b a c k ( null , d e c r y p t e d ); }
Código Fonte 4.2: Função decrypt
4.3.3
Criptografia JSON
As funções anteriores foram desenvolvidas para o processamento de informação simples, ou seja, criptografia de uma cadeia de caracteres que pode representar, ou não, um objeto JSON. No entanto, um dos objetivos deste trabalho está na aplicação de múltiplas cifras a um objeto JSON.
Desta forma foi necessário realizar algum trabalho anterior ao processo de cifra e posterior ao processo de decifra, a este trabalho adicional designamos como cifra JSON e decifra JSON, respetivamente.