Pesquisar este blog

quinta-feira, 4 de novembro de 2010

Criptografia de Fluxo RC4

Existem alguns meios de se trabalhar com criptografia de fluxo neste artigo irei colocar um exemplo da Criptografia de Fluxo RC4 feito em java. Você pode encontrar no Wikipédia uma explicação mais abrangente e detalhada da teoria desta criptografia.
Veja o exemplo completo:

public
class RC4 {
public RC4() {
}
public static void main(String[] args) {
 StringBuffer input,key;
 input = new StringBuffer("FulanosMigration");
 key   = new StringBuffer("ABCDEFGHIJKLMNOPQRSTUVXYZ");
 Crypt(input,key);
 System.out.println("DATA : "+input);
 Crypt(input,key);
 System.out.println("DATA : "+input);
}
static void Crypt(StringBuffer inp,StringBuffer key)
{
 int Sbox[];
 int Sbox2[];
  Sbox  = new int[256];
  Sbox2 = new int[256];
  int i, j, t, x;
 
  String OurUnSecuredKey = "\0";
  char temp , k;
  i = 0;
  j = 0;
  k = 0;
  t = 0;
  x = 0;
  temp = 0;
  //inicializa sbox i
  for( i = 0; i < 256; i++)
  {
   Sbox[i] = i;
  }
 
  j = 0;
  if(key.length() >0)
  {
  for(i = 0; i < 256 ; i++)
  {
   if(j == key.length() )
    j = 0;
   Sbox2[i] = key.charAt(j++);
  }
 }
 else
 {
  for(i = 0; i < 256 ; i++)
  {
   if(j == OurUnSecuredKey.length() +1)
    j = 0;
   Sbox2[i] = OurUnSecuredKey.charAt(j++);
  }
  }
 
  j = 0 ;
  for(i = 0; i < 256; i++)
  {  
   //Troca a posição das letras
   j = (j + Sbox[i] + Sbox2[i]) % 256;
   temp = (char)Sbox[i];
   Sbox[i] = Sbox[j];
   Sbox[j] = temp;
  }
  i = j = 0;
  for(x = 0; x < inp.length() ; x++)
  {
   //incrementa i
   i = (i + 1) % 256;
   //incrementa j
   j = (j + Sbox[i]) % 256;
   temp = (char)Sbox[i];
   Sbox[i] = Sbox[j] ;
   Sbox[j] = temp;
   t = ( Sbox[i] + Sbox[j]) % 256 ;
   k = (char)Sbox[t];
   //xor
   inp.setCharAt(x, (char)(inp.charAt(x) ^ k));
  }
 }
}

Data Encryption Standart (DES)

Este algorítimo de criptografia foi criado na década de 70, o prpósito era criar uma maior proteção dos dados. Fundamentalmente DES realiza somente duas operações sobre sua entrada, deslocamento de bits e substituição de bits. A chave controla exatamente como esse processo ocorre. Ao fazer estas operações repetidas vezes e de uma maneira não-linear, chega-se a um resultado que não pode ser revertido a entrada original sem o uso da chave.

O Exemplo abaixo gera um arquivo txt com a palavra chave e outro com a esta chave criptografada.

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.spec.AlgorithmParameterSpec;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
public class Des
{
    Cipher ecipher;
    Cipher dcipher;
    public static void main(String[] args) {
        try {
           
         SecretKey key = KeyGenerator.getInstance("DES").generateKey();
       
            Des encrypter = new Des(key);
            encrypter.encrypt(new FileInputStream("C:\\teste.txt"),
                new FileOutputStream("C:\\1.txt"));
            encrypter.decrypt(new FileInputStream("C:\\1.txt"),
                new FileOutputStream("C:\\2.txt"));
            System.out.println("teste");
        } catch (Exception e) {
         System.out.println(e.getMessage());
        }
    }
   
    Des(SecretKey key) {
        byte[] iv = new byte[]{
            (byte)0x8E, 0x12, 0x39, (byte)0x9C,
            0x07, 0x72, 0x6F, 0x5A
        };
        AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv);
        try {
            ecipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
            dcipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
            ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
            dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
        } catch (java.security.InvalidAlgorithmParameterException e) {
        } catch (javax.crypto.NoSuchPaddingException e) {
        } catch (java.security.NoSuchAlgorithmException e) {
        } catch (java.security.InvalidKeyException e) {
        }
    }
    byte[] buf = new byte[1024];
    public void encrypt(InputStream in, OutputStream out) {
        try {
            out = new CipherOutputStream(out, ecipher);
            int numRead = 0;
            while ((numRead = in.read(buf)) >= 0) {
                out.write(buf, 0, numRead);
            }
            out.close();
        } catch (java.io.IOException e) {
        }
    }
    public void decrypt(InputStream in, OutputStream out) {
        try {
            in = new CipherInputStream(in, dcipher);
            int numRead = 0;
            while ((numRead = in.read(buf)) >= 0) {
                out.write(buf, 0, numRead);
            }
            out.close();
        } catch (java.io.IOException e) {
        }
    }
}

Espero ter ajudado

quinta-feira, 28 de outubro de 2010

Trabalhando com Arrays em C++

 Nesta postagem quero demonstrar algumas formas de se trabalhar com Arrays estático e dinâmico. O 1º Exemplo é de um array estático simples, veja o código.
int main(){      int smValor[3];
      cout << "Digite um numero: ";      cin >> smValor[0];      cout << "Digite outro número: ";      cin >> smValor[1];      smValor[2] = smValor[0]+smValor[1];      cout << "Resultado da soma: " << smValor[2];      cout << "\n";     
system("pause");
}
       Percebam que declarei um Array de três posições sendo que um das posições serve para receber o cálculo da soma da 1ª e da 2ª posição do Array.
       Em nosso próximo exemplo ainda com array estático procuro demonstrar o mesmo cálculo feito acima mas com a possibilidade de se usar um looping para varrer um array em busca dos valores nele contido.
Veja o código:
#include int main()
{
    int smValor[2];
    int vlrTotal =0;
    int i =1;
    while (i<=2)
   {
        cout << "Digite um numero: ";
        cin >> smValor[i];
        i++;
   }
    i =1;
    while (i<=2)
   {
       vlrTotal = vlrTotal + smValor[i];       i++;
   }
   cout << "Resultado da soma: " << vlrTotal;
   cout << "\n";   
system("Pause");
}
       No código acima foi utilizado o While para fazer a repetição e as instruções para sair e manipular a quantidade de repetições ficou dividida interna e externamente, isto pode ser notado nos pontos onde se encontra i =1; e i++; e while (i<=2) se "for" usado um for ao invés do um "while" isso tudo ficaria em uma única linha.
       Em nosso próximo código vamos trabalhar com Array Dinâmico, "O que significa array dinâmico?", dinâmico quer dizer que não possui um tamanho pré-definido, sendo assim que irá definir o tamanho de nosso array será o usuário, que terá a possibilidade de optar pela quantidade de linhas que nosso array terá. Vejam o código abaixo:
#include int main(){
    int vlrTotal =0;
    int i =1;
    int x =1;
    cout << "Digite a quantidade de números a serem utilizados na soma: ";
    cin >> x;
    int smValor[x];
    while (i<=x)
{
       cout << "Digite um numero: ";
       cin >> smValor[i];
         i++;
    }
    i =1;
    while (i<=x)
    {
        vlrTotal = vlrTotal + smValor[i];
         i++; }
    cout << "Resultado da soma: " << vlrTotal;
    cout << "\n";
    system("pause");
}
       O interessante de se programar em C/C++ é que o mesmo não exige a declaração no cabeçalho do seu código, notem que o Array foi declarado após perguntar ao usuário o tamanho que ele queria para o Array, claro que a pergunta diz "quantidade de números " é simplesmente para facilitar para o usuário, imaginem perguntar "Digite o tamanho do Array a ser utilizado", a primeira pergunta do mesmo seria "hein??", depois "Que isso? Array??".
       A quantidade de linhas que nosso Array terá é determinada por "x". No próximo código iremos trabalhar mais uma vez com Array dinâmico, mas agora com linhas e colunas, vejam o código:
#include int main(){
    int TotLin =1;
    int i =1;
    int x =1;
    int vlr =0;
    cout << "Digite a quantidade de linhas e colunas a serem utilizadas: ";
    cin >> TotLin;
    int smValor[TotLin][TotLin];
   
for(i=1;i<=TotLin;i++){         x = 1;
    for(x=1;x<=TotLin;x++)
           {
                cout << "Digite um nº. para a linha " << i << " coluna " << x << ":";
                cin >> vlr;
                smValor[i][x] = vlr;
           }
    }
    for(i=1;i<=TotLin;i++)   {
           x = 1;
           for(x=1;x<=TotLin;x++)           {
                 cout << smValor[i][x];            }
          cout << endl;
    }
    cout << endl;    system("pause");
}
       No código acima substitui o While por For, notem como o código ficou mais claro, usei também "endl" que substitui em muitas vezes o comando "\n", percebam ainda que neste código o usuário ainda determina o tamanho do Array, só não efetuei cálculo algum, pedi apenas para que exiba os valores contidos no Array.
       Na declaração do Array "int smValor[TotLin][TotLin];", usei o mesmo tamanho para linha e para coluna, mas tudo vai depender de como se deseja trabalhar com os vetores, pois podemos ter por exemplo um vetor de 2 linhas e 10 colunas, cabe a cada um analisar o que deseja com o código.
       Espero que este pequeno tutorial possa ajudar.
Abraços e até a próxima postagem.