Alguem ja se deparou com esse erro ou sabe o q pode ser?
Estou tentando criptografar um arquivo usando Bouncy Castle. Já coloquei o jar do provider dentro de jre/lib/ext… ja fiz download e sobrescrevi os policy files sem restriçoes, já adicionei, dinamicamente, o provider dentro de meu código. Mas quando tento instanciar o Cipher da seguinte forma:
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding","BC");
Dá o seguinte erro:xception in thread "main" java.lang.ExceptionInInitializerError
at javax.crypto.Cipher.getInstance(DashoA12275)
at javax.crypto.Cipher.getInstance(DashoA12275)
at br.com.maxxdata.csframework.concreteutils.UtilCriptografaArquivo.criptografarArquivo(UtilCriptografaArquivo.java:81)
at br.com.maxxdata.csframework.concreteutils.UtilCriptografaArquivo.main(UtilCriptografaArquivo.java:213)
Caused by: java.lang.SecurityException: Cannot set up certs for trusted CAs
at javax.crypto.SunJCE_b.<clinit>(DashoA12275)
... 4 more
Alguém?
Desde já agradeço à atenção,
Saudações
a) Que versão do JDK você está usando
b) Quais os arquivos .jar que você acrescentou
c) Se quiser simplesmente “AES/CBC/PKCS5Padding” use o próprio algoritmo da Sun se você estiver usando JDK 1.4.2_08 ou posterior.
a) Estou usando jdk1.5.0_06.
b) “bcprov-jdk15-132.jar”, “local_policy.jar” e “US_export_policy.jar”.
c) como assim usar o proprio algoritmo da sun? nao entendi. com ficaria meu getInstance do cipher?
a) Como eu mencionei em outro post, PKCS#7 não é um algoritmo e sim um padrão.
b) Baixe estes exemplos do livro Beginning Cryptography with Java (escrito por um dos autores do BouncyCastle) :
http://media.wiley.com/product_ancillary/30/07645963/DOWNLOAD/beg_crypto_examples.zip
c) Além do bcprov, ponha também o bcmail-jdk15-* e os outros (exceto o bctest).
d) Já que está com a mão na massa, use a versão mais nova (1.33)
Por coincidencia ja baixei esses exemplos e até criei um projeto no eclipse pra testa-los… peguei muita idéia deles. A questao eh q acho q to fazendo tudo certo, porem ta rolando alguma coisa sinistra do tipo jce q nao ta assinada sei la. . esse erro de “Cannot set up certs for trusted CAs” ta me cheirando a algo errado fora do meu código. Já gastei dias tentando resolver, por isso tô aki desesperado… meu projeto ja ta com o prazo enforcando-me!!!
Eclipse? Hum… Pode ser que você esteja com algum problema de classpath. O que ocorre se você roda seus programas “na mão” - em uma linha de comando?
Além disso, é melhor instalar o provider naquele arquivo java.security também.
Num pode ser de classpath pq executei os testes desses exemplos aíi e rodaram… tipo akele de ver se o provider ta instalado… entao descarto essa hipótese… mas acho q to quase descobrindo o problema… ja ja volto aki pra postar se consegui ou nao heheh… e se eu tiver mais dúvida tbm… ^^
Opa! tô conseguindo criptografar já ! Olha como ficou o método de criptografar:[code]public void criptografarArquivo(File arquivo, PublicKey chavePublica)
throws CSFException, NoSuchProviderException, InvalidAlgorithmParameterException {
//
try {
Mac mac = Mac.getInstance("HMACSHA1","BC");
chavePublica.hashCode();
SecureRandom sec_rand = new SecureRandom();
byte[] mac_key_bytes = new byte[20]; // Set to correct length for HMACSHA1
sec_rand.nextBytes(mac_key_bytes); // Fill with random data,
Key mac_key = new SecretKeySpec(mac_key_bytes, "HMACSHA1"); // Convert to key object.
mac.init(mac_key); // Initialize.
KeyGenerator key_gen = KeyGenerator.getInstance("AES", "BC"); // Using appropriate key generator.
key_gen.init(128, sec_rand); // Set up with key size and a SecureRandom.
Key aes_key = key_gen.generateKey(); // Generate the Key Object.
byte[] ivBytes = new byte[] {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
//byte[] keyBytes = chavePublica.getEncoded();
//SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");
cipher.init(Cipher.ENCRYPT_MODE, aes_key, ivSpec);
byte [] arquivoEmBytes = UtilArquivos.abrirArquivoEmArrayDeBytes(arquivo);
byte [] arquivoCriptografado = null;
arquivoCriptografado = cipher.doFinal(arquivoEmBytes);
File arqCripto = new File(arquivo.getAbsolutePath()+".p7b");
FileOutputStream fos = new FileOutputStream(arqCripto);
fos.write(arquivoCriptografado);
fos.close();
} catch (NoSuchAlgorithmException e) {
throw new CSFExceptionCritica(e.getMessage(),e.getStackTrace());
} catch (NoSuchPaddingException e) {
throw new CSFExceptionCritica(e.getMessage(),e.getStackTrace());
} catch (InvalidKeyException e) {
throw new CSFExceptionCritica(e.getMessage(),e.getStackTrace());
} catch (IOException e) {
throw new CSFExceptionCritica(e.getMessage(),e.getStackTrace());
} catch (IllegalBlockSizeException e) {
throw new CSFExceptionCritica(e.getMessage(),e.getStackTrace());
} catch (BadPaddingException e) {
throw new CSFExceptionCritica(e.getMessage(),e.getStackTrace());
}
}[/code]
agora quero pegar informações sobre esse arquivo criptografado, isso é possível?? Desse jeito q eu criptografei tem como pegar informações do arquivo se eu tivesse extraído essa chave pública aí de um certificado??
Do jeito que você escreveu, você só gerou um monte de dados criptografados com uma chave simétrica. Pior: cada vez que você rodar esse programa, você vai ter uma chave diferente, e você nunca vai conseguir decifrar esse troço.
Você ainda não leu os exemplos direito…
é q isso daí eu só fiz pra ter certeza q ta tudo instalado e configurado corretamente… Quero saber o seguinte, se eu tivesse usado uma chave publica de um certificado ao inves dessas chaves doidonas aí q eu criei, eu conseguiria recuperar alguma informaçao depois do arquivo encriptado?
Vamos explicar como é que funciona o PKCS#7 envelopedData.
Esse formato contém, entre outras coisas:
- Os dados criptografados com uma chave simétrica gerada aleatoriamente;
- A chave simétrica criptografada com a chave pública do destinatário.
Não estou com o padrão aqui para dizer se é possível também mandar mais alguma coisa, como o número de série do certificado X.509 do destinatário ou outra coisa. Só olhando o padrão.
O destinatário deve fazer o seguinte:
- Decifrar a chave simétrica, usando a sua chave privada.
- Decifrar os dados, usando a chave simétrica decifrada.
Então vc se refere a esse exemplo dakele pacote q falou no inicio né?!
[code]/**
-
Demonstrate creation and processing a public key recipient enveloped-message
-
with matching of the RID to a certificate to make sure we have the right recipient.
*/
public class KeyTransEnvelopedDataWithCertMatchExample
{
public static void main(String[] args)
throws Exception
{
KeyStore credentials = Utils.createCredentials();
PrivateKey key = (PrivateKey)credentials.getKey(Utils.END_ENTITY_ALIAS, Utils.KEY_PASSWD);
Certificate[] chain = credentials.getCertificateChain(Utils.END_ENTITY_ALIAS);
X509Certificate cert = (X509Certificate)chain[0];
// set up the generator
CMSEnvelopedDataGenerator gen = new CMSEnvelopedDataGenerator();
gen.addKeyTransRecipient(cert);
// create the enveloped-data object
CMSProcessable data = new CMSProcessableByteArray("Hello World!".getBytes());
CMSEnvelopedData enveloped = gen.generate(
data,
CMSEnvelopedDataGenerator.AES256_CBC, "BC");
// recreate
enveloped = new CMSEnvelopedData(enveloped.getEncoded());
// set up to iterate through the recipients
RecipientInformationStore recipients = enveloped.getRecipientInfos();
CertStore certStore = CertStore.getInstance("Collection", new CollectionCertStoreParameters(Collections.singleton(cert)), "BC");
Iterator it = recipients.getRecipients().iterator();
RecipientInformation recipient = null;
while (it.hasNext())
{
recipient = (RecipientInformation)it.next();
if (recipient instanceof KeyTransRecipientInformation)
{
// match the recipient ID
Collection matches = certStore.getCertificates(recipient.getRID());
if (!matches.isEmpty())
{
// decrypt the data
byte[] recData = recipient.getContent(key, "BC");
// compare recovered data to the original data
if (Arrays.equals((byte[])data.getContent(), recData))
{
System.out.println("data recovery succeeded");
break;
}
else
{
System.out.println("data recovery failed");
break;
}
}
}
}
if (recipient == null)
{
System.out.println("could not find a matching recipient");
}
}
}[/code]
Hum… Esse conceito de Recipient aí ta me confundindo pra caramba. Fiz minha versão desse exemplo aí pra carregar do token, mas até agora num deu certo… acho q esse treco de recipiente ser o destinatário q ta me confundindo… o recipiente nesse momento aki // decrypt the data
byte[] recData = recipient.getContent(key, "BC");
Como pode pegar um arquivo encriptado de um recipiente entao? afinal o que ele ta fazendo nessa linha??
Desde já agradeço a atenção,
O tal exemplo que você está mostrando é um exemplo com “ida e volta” - ou seja, tem a parte que envelopa dados com PKCS#7, e a parte que decifra os tais dados.
Entao, eu separei em dois métodos esse exemplo aí… Um q criptografa e outro q descriptografa e verifica se o descriptado compara com o antigo antes da criptografada ^ ^. ôo!!
Só q na hora de descriptografar byte[] recData = recipient.getContent(key, "BC");
Ele da uma exception doidona assim: xception in thread "main" java.security.NoSuchProviderException: No such provider: org.mozilla.jss.JSSProvider
at javax.crypto.Cipher.getInstance(DashoA12275)
at org.bouncycastle.cms.KeyTransRecipientInformation.getContentStream(Unknown Source)
at org.bouncycastle.cms.RecipientInformation.getContent(Unknown Source)
at br.com.maxxdata.csframework.concreteutils.UtilCriptografaDescriptografa.descriptografa(UtilCriptografaDescriptografa.java:125)
Quer q eu poste o código pra vc ver como ficou Thingol?? Se é q vc vai ter saco heheh^ ^" eu sou muito chato…o_O