Para que qualquer Estrutura Distribuída ou Infraestrutura seja bem-sucedida hoje, ela precisa ter um amplo suporte para o desenvolvimento de soluções seguras. O Microsoft .NET é desenvolvido de baixo para cima com a segurança em mente. Possui uma infraestrutura de segurança eclética.

A segurança é um tópico amplo e pode ser amplamente dividido em

  1. Autenticação
  2. Autorização
  3. Privacidade ou Confidencialidade
  4. Integridade dos dados
  5. Não-repúdio

Enquanto a autenticação é sobre provar a identidade de uma entidade de segurança para outra, a autorização é sobre o controle do acesso a recursos protegidos com base na identidade. Privacidade lida com a prevenção de eaves soltando de mensagens enviadas através do fio. A Integridade dos Dados garante que a mensagem não seja adulterada em trânsito. O não repúdio garante que o autor da mensagem/dados não possa negar responsabilidade.

O Microsoft .NET tem soluções pré-criadas para todos eles em cada domínio de aplicativo, ou seja, ASP. NET, Web Services, Serviced Component etc. Ele permite a construção de aplicativos seguros por configuração simples, como em ASP.NET a segurança programável de pleno direito, como na segurança de acesso ao código e criptografia.

Criptografia

A criptografia é a arte e a ciência de manter as mensagens seguras.

Quando uma mensagem é transferida de um lugar para outro, seu conteúdo está prontamente disponível para um bisbilhoteiro. Uma ferramenta simples de monitoramento de rede pode expor toda a mensagem enviada de um computador para outro de forma gráfica. Para que um aplicativo distribuído ou de N camadas seja seguro, todas as mensagens enviadas na rede devem ser embaralhadas de uma maneira que seja computacionalmente impossível para qualquer um lê-las.

No mundo da criptografia, a mensagem que precisa ser protegida é chamada de texto sem formatação ou texto não criptografado. A forma embaralhada da mensagem é chamada de texto cifrado. O processo de conversão de um texto sem formatação em texto cifrado é chamado de criptografia. O processo de reconversão do texto cifrado em texto sem formatação é chamado de descriptografia. Algoritmos de criptografia (cifras) são funções matemáticas usadas para criptografia e descriptografia.

Para que a criptografia seja usada em soluções práticas, os algoritmos usados para criptografia e descriptografia devem ser tornados públicos. Isso é possível usando um fluxo de bytes chamado Key. Para que o algoritmo enquadre um texto sem formatação para texto cifrado e para decifrá-lo de volta para texto sem formatação, ele precisa de chave.

CryptE1.gif

Criptografia de chave simétrica

A criptografia de chave simétrica usa a mesma chave, chamada de chave secreta, para criptografia e descriptografia. Os usuários que trocam dados mantêm essa chave para si mesmos. A mensagem criptografada com uma chave secreta só pode ser descriptografada com a mesma chave secreta.

O algoritmo usado para criptografia de chave simétrica é chamado de algoritmo de chave secreta. Como os algoritmos de chave secreta são usados principalmente para criptografar o conteúdo da mensagem, eles também são chamados de algoritmos de criptografia de conteúdo.

A principal vulnerabilidade do algoritmo secret-key é a necessidade de compartilhar a secret-key. Uma maneira de resolver isso é derivando a mesma chave secreta em ambas as extremidades de uma cadeia de texto fornecida pelo usuário (senha) e o algoritmo usado para isso é chamado de algoritmo de criptografia baseado em senha. Outra solução é enviar com segurança a chave secreta de uma extremidade para a outra. Isso é feito usando outra classe de criptografia chamada algoritmo assimétrico, que é discutido mais adiante.

A força da criptografia de chave simétrica depende do tamanho da chave usada. Para o mesmo algoritmo, criptografar usando uma chave mais longa é mais difícil de quebrar do que aquela feita usando uma chave menor. A força da chave não é o forro com o comprimento da chave, mas dobra a cada bit adicional.

A seguir estão alguns dos algoritmos populares de chave secreta e o tamanho da chave que eles usam
RC2 - 64 bits DES 64 bits 3DES 192 bits AES 256 bits IDEA 128 bits CAST 128 bits (CAST256 usa chave de 256 bits

)
Parâmetros do algoritmo:

  1. Modo de criptografia Existem dois tipos de cifras de chave secreta, cifras de bloco e cifras de fluxo As cifras
    de bloco convertem bloco de comprimento fixo de texto sem formatação em texto cifrado do mesmo tamanho. A maioria das cifras de bloco usa um tamanho de bloco de 64 bits. Quando o tamanho da mensagem é maior do que o do tamanho do bloco, a mensagem é dividida em vários blocos e cada bloco é criptografado separadamente. Existem diferentes modos nos quais uma cifra de bloco pode criptografar esses blocos. Ou seja, Cipher Block Chaining (CBC), Electronic Codebook (BCE) ou Cipher Feedback (CFB). Destes modo CBC é mais comumente usado. No Modo CBC, cada bloco de texto sem formatação é XORed com o bloco de texto cifrado anterior antes de ser criptografado. Algumas cifras de bloco famosas são DES, 3DES, IDEA, SAFER, Blowfish e Skipjack (usado pela Agência de Segurança Nacional dos EUA).
    As Cifras de Fluxo operam em pequenos grupos de bits, normalmente aplicando operações XOR bit a bit a elas usando a chave como uma sequência de bits. Algumas cifras de fluxo famosas incluem RC4 e SEAL.
  2. Vetor de inicialização
    Como as cifras de bloco que trabalham nos modos CBC XOR cada bloco com o bloco criptografado anterior, o primeiro bloco da mensagem precisa de uma matriz de bytes, do mesmo tamanho de bloco, com a qual será XORed Essa matriz de bytes é chamada IV ou Vetor
    de Inicialização.
    A seguir estão algumas cifras de bloco com seu tamanho
    de bloco normal DES - 64 bits 3DES 64 bits AES 128 bits
  3. Preenchimento

    Muitas vezes, o último bloco da mensagem será menor que o tamanho de bloco esperado, caso em que uma cadeia de caracteres predeterminada será repetidamente adicionada ao final do bloco para chegar ao tamanho esperado. Por exemplo, se o tamanho do bloco for de 64 bits e o último bloco tiver apenas 40 bits, 24 bits de preenchimento serão adicionados a ele. Havia duas maneiras de adicionar o pad, seja adicionando zeros ou o número de bytes que precisam ser adicionados (neste caso, será 3).

Criptografia de chave assimétrica

A criptografia de chave assimétrica usa chaves diferentes para criptografia e descriptografia. Essas duas chaves estão matematicamente relacionadas e formam um par de chaves. Uma dessas duas chaves deve ser mantida privada, chamada de chave privada, e a outra pode ser tornada pública (pode até ser enviada por e-mail), chamada de chave pública. Por isso, isso também é chamado de Criptografia de Chave Pública.

Uma chave privada é normalmente usada para criptografar o resumo da mensagem; em tal aplicativo, um algoritmo de chave privada é chamado de algoritmo de criptografia message-digest. Uma chave pública é normalmente usada para criptografar a chave secreta; em tal aplicativo, o algoritmo de chave privada é chamado de algoritmo de criptografia de chave.

Algoritmos populares de chave privada são RSA (inventado por Rivest, Shamir e Adlemen) e DSA (Digital Signature Algorithm). Enquanto para um uso comum de RSA, um tamanho de chave de 768 pode ser usado, mas para uso corporativo um tamanho de chave de 1024 e para informações extremamente valiosas um tamanho de chave de 2048 deve ser usado.

A criptografia de chave assimétrica é muito mais lenta do que a criptografia de chave simétrica e, portanto, eles são usados apenas para trocas de chaves e assinaturas digitais.

Para saber mais sobre criptografia, consulte o site RAS Security. http://www.rsasecurity.com/rsalabs/faq/3.html

Criptografia no Microsoft .NET

Microsoft.NET tem classes que estendem os serviços de criptografia fornecidos pela CryptoAPI do Windows.

O namespace System.Security.Cryptography do Common Language runtime fornece classes para

  1. Criptografia de chave simétrica
  2. Criptografia de chave assimétrica
  3. Hash
  4. Certificados Digitais
  5. Assinaturas XML

A criptografia de chave simétrica e a criptografia de chave assimétrica são discutidas neste artigo. Hashing, Certificados Digitais e Assinaturas XML serão discutidos nos artigos subsequentes.

Criptografia de chave simétrica no .NET:

Os algoritmos simétricos são implementados usando um padrão de herança de três níveis.
A classe abstrata de nível raiz, SymmetricAlgorithm (System.Security.Cryptography.SymmetricAlgorithm), especifica que é um algoritmo simétrico. As classes intermediárias são nomeadas após um tipo particular de algoritmo simétrico que elas implementam e também são abstratas. A classe de nível final fornece a implementação completa dos algoritmos simétricos usando os provedores de serviços criptográficos da CryptoAPI do Windows ou implementando completamente o algoritmo no .NET. Enquanto as classes anteriores têm o sufixo CryptoServiceProvider, o último tem o sufixo Gerenciado.

CryptE2.gif

Quando a classe concreta (RC2CryptoServiceProvider, DESCryptoService Provider, TrippleDESCryptoService Provider e RijndaelManaged) é instanciada, o construtor padrão gera uma chave secreta forte, inicializa o IV, define valores sensíveis para preenchimento e modo.

RijndaelManaged rj =new RijndaelManaged();
Console.WriteLine(“AES Mode is : “ + rj. Modalidade);
Console.WriteLine(“O preenchimento AES é: “ + rj. Preenchimento );
Console.WriteLine(“Tamanho da chave AES: “ + rj. KeySize);

Isso gerará uma saída como abaixo
AES Modo é: CBC
AES Padding é: PKCS7
AES Tamanho da chave: 256

Criptografia de chave assimétrica no .NET:

Semelhante aos algoritmos de chave simétrica, a assimétrica também é implementada usando um padrão de herança de três níveis.

Quando a classe concreta (RSACryptoServiceProvider ou DSACryptoService Provider) é instanciada, o construtor padrão sempre gera um par de chaves aleatórias (valores de chave fortes). Além disso, os algoritmos assimétricos podem ser feitos para recuperar o par de chaves existente do contêiner de chaves do CSP.

CryptE3.gif

// Create the CspParameters object
CspParameters cp = new CspParameters();
// Set the key container name that has the RSA key pair
cp.KeyContainerName = "ApplicationKeyContainer";
// Create the RSA CSP passing CspParameters object
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(cp);
Console.WriteLine("RSA Key Size :" + rsa.KeySize);
Console.WriteLine("RSA Key is : \n" + rsa.ToXmlString(true));

Isso gerará uma saída como abaixo (editada para brevidade)

Tamanho da chave RSA: 1024 A chave RSA é :

<RSAKeyValue>
<Modulus>t9Kue9bSrE=</Modulus>
<Exponent>AQAB</Exponent>
<P>7AL5vyAbw==</P>
<Q>x2QxA23w==</Q>
<DP>bLO+qHw==</DP>
<DQ>h6S52sQ==</DQ>
<InverseQ>vftt4iig==</InverseQ>
<D>YBSd0=</D>
</RSAKeyValue>

CspParameters tem os parâmetros para identificar um Provedor de Serviços Criptográficos específico e um contêiner de chave específico para chaves.

System.Security.Cryptography.CspParameters csp = new CspParameters();
// Set the key container name that has the RSA key pair
csp.KeyContainerName = "TestMe2";
//Set the CSP Provider Type PROV_RSA_FULL
csp.ProviderType = 1;
//Set the CSP Provider Name
csp.ProviderName = "Microsoft Base Cryptographic Provider v1.0";
//Create a DSA cypher and intialaise it with the CspParameters
RSACryptoServiceProvider _cipher = new RSACryptoServiceProvider(csp);
Console.WriteLine("Cipher :" + _cipher.ToString());
Console.WriteLine("Key : " + _cipher.ToXmlString(true));
Console.WriteLine("Key Size : " + _cipher.KeySize);
Console.WriteLine("KeyExchangeAlgorithm : " + _cipher.KeyExchangeAlgorithm );
Console.WriteLine("SignatureAlgorithm : " + _cipher.SignatureAlgorithm );

Isso gerará uma saída conforme abaixo

Cifra: System.Security.Cryptography.RSACryptoServiceProvider Chave
:

<RSAKeyValue><Modulus>2FccOXusxV+lstX8frCDvw1z6gpl1VDDnwzoLDVHJ3zWjtyKqc2lObTGDu2a
JHXcTU7RvGodTH1Xdh/woJJbeCYDtEk5zMfF1FOjugEhOnWaCkQm73d4Tr33e4ofn/rlqh983rSJlpSu5L0
CAJKtDZ+WaHQhLsFqtOPQUQL4qH0=</Modulus><Exponent>AQAB</Exponent>
<P>+Sft+l8T0IuaOQL6zMujcJklopLK9pMGeGWyMXJvPqDQwOXh2tBkhuQTSqP7QH8yJ7
AZ03trqZ/h0rFuSSy20Q==</P><Q>3khrfySCAEVHVTTvgXNXvQu1M/xaEuwhxw57j4VXJVANwZ
TCdNtQwprgmoB5q0jLLRRZP/pNCA1LqOy8+2kZ7Q==</Q><DP>+Hm3vS9AhYQTo7OzBrY3Ir24a
K9YNhteIofY87MZ+i1KwnT/jsaw2k1uZ8utcB7pl+bpepzlO960yPgl8lfjYQ==</DP><DQ>x4OpOQ3D
wgps5IYHE+I7tmtz0Z2IG8Pm7YyKS2AbwFoCfubPQ6Q28PWi9AqtKpjEBUpmcY5w5fFJH+6eEetc
YQ==</DQ><InverseQ>5IvEUcDA7UIhx0FU9nY8ZnC/P+GaT/54mR2xe9Hlp1XQsOtToFn1Dzd9Evx
FcTqO6hGntRAPLqNBFle3i5xvRA==</InverseQ><D>j9ib87zADByk2FxgHvzPHOGdCSkQvN2Ot
NqoJXznauIe567MpEsQaWZBqvthWozjhqO54UXNZWaSGQDzxlCKcAefAurJhZJ/HE0Yemm+
9cSqynZcT0UAPRAxzi7KSGuPKTOkn58hyQNtRP7DWHAILuUQ5c75Mu8UXkxxy5bjsgE=</D>
</RSAKeyValue>

Key Size : 1024

KeyExchangeAlgorithm : RSA-PKCS1-KeyEx

SignatureAlgorithm : http://www.w3.org/2000/09/xmldsig#rsa-sha1

Windows 2000 Professional vem com o seguinte CSP

CryptE4.gif

Para obter mais detalhes sobre os tipos de provedor CSP, consultehttp://msdn.microsoft.com/library/default.asp?url=/library/en-us/security/Security/cryptographic_provider_types.asp

Programação baseada em fluxo:

Namespaces criptográficos usa o mesmo design orientado a Stream (System.IO.Stream) que permeia o .NET Framework de rede (System.Net) para XML (System.XML). Uma nova classe chamada CryptoStream (System.Security.Cryptography.CryptoStream) derivada de System.IO.Stream é usada para criptografia e descriptografia de dados.

O trecho a seguir mostra como criptografar uma cadeia de caracteres usando RijndaelManaged (por exemplo, consulte TextEncrpytion Class)

//Create a memory stream to which CryptoStream
//will write the cipher text
MemoryStream ciphertextmem = new MemoryStream();

//Create a CryptoStream in Write Mode; initialise with the
//Rijndael's Encryptor ICryptoTransform
CryptoStream crystm = new CryptoStream(ciphertextmem,
  _rj.CreateEncryptor(), CryptoStreamMode.Write);

//Encode the passed plain text string into Unicode byte stream
Byte[] plaintextbyte = new UnicodeEncoding().GetBytes(plaintext);
//Write the plaintext byte stream to CryptoStream
crystm.Write(plaintextbyte, 0, plaintextbyte.Length);

//don't forget to close the stream
crystm.Close();
//Extract the ciphertext byte stream and close the MemoryStream
Byte[] ciphertextbyte = ciphertextmem.ToArray();

ciphertextmem.Close();

//Encode the ciphertext byte into Unicode string
string ciphertext = new UnicodeEncoding().GetString(ciphertextbyte);

Following snippet shows how to decrypt a string using RijndaelManaged
//Create a memory stream from which CryptoStream will read the
//cipher text
MemoryStream ciphertextmem = new MemoryStream(new UnicodeEncoding().GetBytes(ciphertext));

//Create a CryptoStream in Read Mode; initialise withe the
//Rijndael's Decryptor ICryptoTransform
CryptoStream crystm = new CryptoStream(ciphertextmem, _rj.CreateDecryptor(), CryptoStreamMode.Read);
//Create a temporary memory stream to which we will copy the
//plaintext byte array from CryptoStream
MemoryStream plaintextmem = new MemoryStream();

do {
  //Create a byte array into which we will read the plaintext
  //from CryptoStream
  Byte[] buf = new Byte[100];

  //read the plaintext from CryptoStream
  int actualbytesread = crystm.Read(buf, 0, 100);

  //if we have reached the end of stream quit the loop
  if (0 == actualbytesread)
    break;

  //copy the plaintext byte array to MemoryStream
  plaintextmem.Write(buf, 0, actualbytesread);

} while (true);
//don't forget to close the streams
crystm.Close();

ciphertextmem.Close();

//Extract the plaintext byte stream and close the MemoryStream
Byte[] plaintextbyte = plaintextmem.ToArray();

plaintextmem.Close();
//Encode the plaintext byte into Unicode string
string plaintext = new UnicodeEncoding().GetString(plaintextbyte);

Configurando a criptografia

Os namespaces criptográficos usam a configuração onipresente baseada em XML para os algoritmos. cryptoNameMapping fornece nomes amigáveis para as cifras (algoritmos), esses nomes amigáveis podem ser usados a partir dos métodos estáticos Create das classes abstratas (System.Secyrity.Cryptography.AsymmetricAlgorithm, System.Secyrity.Cryptography.SymmetricAlgorithm) para criar uma classe de cifra específica

Por exemplo, o arquivo de configuração a seguir mostra duas cifras simétricas personalizadas, MyCryptoClass1 e MyCryptoClass2 implementadas no assembly MyAssembly.

<cryptographySettings>
<cryptoNameMapping>
<cryptoClasses>
<cryptoClass MyCrypto1="MyCryptoClass, MyAssembly Culture='en', PublicKeyToken=a5d015c7d5a0b012, Version=1.0.0.0"/>
<cryptoClass MyCrypto2="MyCryptoClass2, MyAssembly Culture='en', PublicKeyToken=a5d015c7d5a0b012, Version=1.0.0.0"/>
</cryptoClasses>
<nameEntry name="System.Security.Cryptography. SymmetricAlgorithm" class=" MyCrypto1"/>
</cryptoNameMapping>
</cryptographySettings>

Dessas duas classes, MyCryptoClass1 é definida como a classe padrão para SymmetricAlgorithm

//Cria a implementação padrão, que é MyCrypto1.  
SymmetricAlgorithm \_cipher = SymmetricAlgorithm.Create();  
//Cria a implementação MyCrypto2.  
SymmetricAlgorithm \_cipher = SymmetricAlgorithm.Create( MyCrypto2);

Por padrão, sem alterações de configuração, a implementação padrão criada para SymmetricAlgorithm é RijndaelManaged e para AsymmetricAlgorithm é RSACryptoServiceProvider

CryptographySettings deve estar dentro do como

<configuration>
<mscorlib>
<cryptographySettings>
..
..
</cryptographySettings>
</mscorlib>
</configuration>

A classe CryptoConfig (System.Security.Cryptography.CryptoConfig) é a classe auxiliar para acessar as Configurações de criptografia.

    AsymmetricAlgorithm \_cipher = (AsymmetricAlgorithm) CryptoConfig.CreateFromName("System.Security.Cryptography.DSA");  
Console.WriteLine("Cifra :" + \_cipher. ToString());  
Console.WriteLine("Chave: " + \_cipher. ToXmlString(true));  
Console.WriteLine("Tamanho da chave: " + \_cipher. KeySize);  
Console.WriteLine("KeyExchangeAlgorithm : " + \_cipher. KeyExchangeAlgorithm );  
Console.WriteLine("SignatureAlgorithm : " + \_cipher. SignatureAlgorithm );
Isso gerará uma saída como abaixo (editada para brevidade)
Cifra: System.Security.Cryptography.DSACryptoServiceProvider Key
<DSAKeyValue\><P>uZPdyk\=</P\><Q>+gxcEM=</Q\><G\>O+  
R9ws=</G\><Y>k=</Y\><J>w24</J\><Seed>TA8\=</Seed\><PgenCounter\>AeA\=  
</PgenCounter\><X\>9M.. 5Bpc=</X\></DSAKeyValue\>

Tamanho da chave: 1024

KeyExchangeAlgorithm: SignatureAlgorithm:

http://www.w3.org/2000/09/xmldsig#dsa-sha1

DSA não suporta algoritmo de criptografia de chave (KeyExchnage Algorithm) e, portanto, a saída não tem nada para KeyExchangeAlgorithm :. Considerando que ele suporta DSS, portanto, ele temhttp://www.w3.org/2000/09/xmldsig#dsa-sha1para SignatureAlgorithm

Artigo seguinte

Este artigo ignorou intencionalmente a função relacionada a assinatura e hash das classes de criptografia como eles são tratados nos artigos subsequentes.

Os artigos subsequentes tratam de Hashing, Assinaturas, Certificados, XML- Assinatura e XML- Criptografia Eles também se aprofundam nos detalhes do uso de Assinaturas Digitais, Envelopes Digitais, Certificados Digitais em Microsoft.Net.


Artigo Original