Pessoal, estou fazendo um trabalho de Criptografia, e quero demonstrar um exemplo com RSA.
Procurei bastante no Google, e até achei exemplos. Só q todos eles geram a chave automaticamente, digo, não permite que eu por exemplo criptografe com uma chave publica q vou receber em tempo de execução. Ele se limita ao par de chaves gerado na hora.
Dei uma olhada aki no forum e vi uma pessoa c a msm duvida q eu, e recomendou-se o Bouncy Castle. A minha duvida é como eu uso essa biblioteca para resolver meu problema. Pois nao achei nenhum exemplo, e se existe alguma solução melhor.
Desde ja agradeço!
Rsa
7 Respostas
Cara dá uma procurada em SecretKeyFactory, talvez ajude não usei com RSA apenas com DES mas segue um exemplo:
public SecretKey generate(String key) throws Exception {
byte[] byteKey = key.getBytes();
SecretKey cryptKey = null;
DESKeySpec desKeySpec = new DESKeySpec(byteKey);
SecretKeyFactory factory = SecretKeyFactory.getInstance(cryptType);
cryptKey = factory.generateSecret(desKeySpec);
return cryptKey;
}
Ao invés de usar DESKeySpec imagino que você vá usar a classe PBEKeySpec.
[]s
Vlw pela dica, mas se não me engano o DES não é um algoritmo assimetrico(q é o q estou pesquisando), onde se usa a chave publica e a chave privada.
Vlw!
Cara,
Eu fiz algo parecido com RSA (JAVA 1.5 já tem suporte, não precisa da Bouncy Castle). No meu caso, eu serializei a chave pública num arquivo e privada em outro, algo como pubKey.ser e privKey.ser. Existe uma maneira mais prática para armazenar as chaves, via a ferramenta Keytool (guarda as chaves num keystore).
Procura estudar as classes Cipher e KeyPairGenerator.
Existem vários links no guj sobre o assunto, por exemplo: http://www.guj.com.br/posts/list/39291.java
Abs,
Francisco
Vlw pela dica, mas vc disse q nao precisa usar o Bouncy Castle, e neste link esta usando ele.
Se alguem tiver um exemplo mais simples eu agradeço.
Mas esse ja ajudou bastante. Vlw!!!
up
pessoal, resolvido, qm quiser, o codigo segue abaixo:
Obs.: vc deve ter a biblioteca do Bouncy Castle: http://www.bouncycastle.org/java.html
/*
* RSA.java
*
* Created on 8 de Novembro de 2007, 11:38
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
package Criptografia;
import java.io.*;
import java.security.*;
import java.security.spec.*;
import javax.crypto.*;
import org.bouncycastle.jce.provider.*;
import sun.misc.*;
/**
*
* <p>Title: RSAEncryptUtil</p>
* <p>Description: Utility class that helps encrypt and decrypt strings using RSA algorithm</p>
* @author Aviran Mordo http://aviran.mordos.com
* @version 1.0
*/
public class RSA
{
protected static final String ALGORITHM = "RSA";
/**
* Init java security to add BouncyCastle as an RSA provider
*/
public static void init()
{
Security.addProvider(new BouncyCastleProvider());
}
/**
* Generate key which contains a pair of privae and public key using 1024 bytes
* @return key pair
* @throws NoSuchAlgorithmException
*/
public static KeyPair generateKey() throws NoSuchAlgorithmException
{
KeyPairGenerator keyGen = KeyPairGenerator.getInstance(ALGORITHM);
keyGen.initialize(1024);
KeyPair key = keyGen.generateKeyPair();
return key;
}
/**
* Encrypt a text using public key.
* @param text The original unencrypted text
* @param key The public key
* @return Encrypted text
* @throws java.lang.Exception
*/
public static byte[] encrypt(byte[] text, PublicKey key) throws Exception
{
byte[] cipherText = null;
try
{
//
// get an RSA cipher object and print the provider
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
// encrypt the plaintext using the public key
cipher.init(Cipher.ENCRYPT_MODE, key);
cipherText = cipher.doFinal(text);
}
catch (Exception e)
{
}
return cipherText;
}
/**
* Encrypt a text using public key. The result is enctypted BASE64 encoded text
* @param text The original unencrypted text
* @param key The public key
* @return Encrypted text encoded as BASE64
* @throws java.lang.Exception
*/
public static String encrypt(String text, PublicKey key) throws Exception
{
String encryptedText=null;
try
{
byte[] cipherText = encrypt(text.getBytes("UTF8"),key);
encryptedText = encodeBASE64(cipherText);
}
catch (Exception e)
{
}
return encryptedText;
}
/**
* Decrypt text using private key
* @param text The encrypted text
* @param key The private key
* @return The unencrypted text
* @throws java.lang.Exception
*/
public static byte[] decrypt(byte[] text, PrivateKey key) throws Exception
{
byte[] dectyptedText = null;
try
{
// decrypt the text using the private key
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, key);
dectyptedText = cipher.doFinal(text);
}
catch (Exception e)
{
}
return dectyptedText;
}
/**
* Decrypt BASE64 encoded text using private key
* @param text The encrypted text, encoded as BASE64
* @param key The private key
* @return The unencrypted text encoded as UTF8
* @throws java.lang.Exception
*/
public static String decrypt(String text, PrivateKey key) throws Exception
{
String result=null;
try
{
// decrypt the text using the private key
byte[] dectyptedText = decrypt(decodeBASE64(text),key);
result = new String(dectyptedText, "UTF8");
}
catch (Exception e)
{
}
return result;
}
/**
* Convert a Key to string encoded as BASE64
* @param key The key (private or public)
* @return A string representation of the key
*/
public static String getKeyAsString(Key key)
{
// Get the bytes of the key
byte[] keyBytes = key.getEncoded();
// Convert key to BASE64 encoded string
BASE64Encoder b64 = new BASE64Encoder();
return b64.encode(keyBytes);
}
/**
* Generates Private Key from BASE64 encoded string
* @param key BASE64 encoded string which represents the key
* @return The PrivateKey
* @throws java.lang.Exception
*/
public static PrivateKey getPrivateKeyFromString(String key) throws Exception
{
KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
BASE64Decoder b64 = new BASE64Decoder();
EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(b64.decodeBuffer(key));
PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);
return privateKey;
}
/**
* Generates Public Key from BASE64 encoded string
* @param key BASE64 encoded string which represents the key
* @return The PublicKey
* @throws java.lang.Exception
*/
public static PublicKey getPublicKeyFromString(String key) throws Exception
{
BASE64Decoder b64 = new BASE64Decoder();
KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(b64.decodeBuffer(key));
PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);
return publicKey;
}
/**
* Encode bytes array to BASE64 string
* @param bytes
* @return Encoded string
*/
private static String encodeBASE64(byte[] bytes)
{
BASE64Encoder b64 = new BASE64Encoder();
return b64.encode(bytes);
}
/**
* Decode BASE64 encoded string to bytes array
* @param text The string
* @return Bytes array
* @throws IOException
*/
private static byte[] decodeBASE64(String text) throws IOException
{
BASE64Decoder b64 = new BASE64Decoder();
return b64.decodeBuffer(text);
}
/**
* Encrypt file using 1024 RSA encryption
*
* @param srcFileName Source file name
* @param destFileName Destination file name
* @param key The key. For encryption this is the Private Key and for decryption this is the public key
* @param cipherMode Cipher Mode
* @throws Exception
*/
public static void encryptFile(String srcFileName, String destFileName, PublicKey key) throws Exception
{
encryptDecryptFile(srcFileName,destFileName, key, Cipher.ENCRYPT_MODE);
}
/**
* Decrypt file using 1024 RSA encryption
*
* @param srcFileName Source file name
* @param destFileName Destination file name
* @param key The key. For encryption this is the Private Key and for decryption this is the public key
* @param cipherMode Cipher Mode
* @throws Exception
*/
public static void decryptFile(String srcFileName, String destFileName, PrivateKey key) throws Exception
{
encryptDecryptFile(srcFileName,destFileName, key, Cipher.DECRYPT_MODE);
}
/**
* Encrypt and Decrypt files using 1024 RSA encryption
*
* @param srcFileName Source file name
* @param destFileName Destination file name
* @param key The key. For encryption this is the Private Key and for decryption this is the public key
* @param cipherMode Cipher Mode
* @throws Exception
*/
public static void encryptDecryptFile(String srcFileName, String destFileName, Key key, int cipherMode) throws Exception
{
OutputStream outputWriter = null;
InputStream inputReader = null;
try
{
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
String textLine = null;
//RSA encryption data size limitations are slightly less than the key modulus size,
//depending on the actual padding scheme used (e.g. with 1024 bit (128 byte) RSA key,
//the size limit is 117 bytes for PKCS#1 v 1.5 padding. (http://www.jensign.com/JavaScience/dotnet/RSAEncrypt/)
byte[] buf = cipherMode == Cipher.ENCRYPT_MODE? new byte[100] : new byte[128];
int bufl;
// init the Cipher object for Encryption...
cipher.init(cipherMode, key);
// start FileIO
outputWriter = new FileOutputStream(destFileName);
inputReader = new FileInputStream(srcFileName);
while ( (bufl = inputReader.read(buf)) != -1)
{
byte[] encText = null;
if (cipherMode == Cipher.ENCRYPT_MODE)
{
encText = encrypt(copyBytes(buf,bufl),(PublicKey)key);
}
else
{
encText = decrypt(copyBytes(buf,bufl),(PrivateKey)key);
}
outputWriter.write(encText);
}
outputWriter.flush();
}
catch (Exception e)
{
}
finally
{
try
{
if (outputWriter != null)
{
outputWriter.close();
}
if (inputReader != null)
{
inputReader.close();
}
}
catch (Exception e)
{
// do nothing...
} // end of inner try, catch (Exception)...
}
}
public static byte[] copyBytes(byte[] arr, int length)
{
byte[] newArr = null;
if (arr.length == length)
{
newArr = arr;
}
else
{
newArr = new byte[length];
for (int i = 0; i < length; i++)
{
newArr[i] = (byte) arr[i];
}
}
return newArr;
}
}
Caro amigo Samuelhenrique,
Este código encripta em 1024bit e depois transforma em um hash 128byte?