Java AES: нет установленного поставщика поддерживает этот ключ: javax.криптографический.спекуляция.SecretKeySpec
Я пытаюсь настроить 128-битное шифрование AES, и я получаю исключение, брошенное на мой шифр.init:
No installed provider supports this key: javax.crypto.spec.SecretKeySpec
я генерирую ключ на стороне клиента, используя следующий код:
private KeyGenerator kgen;
try {
kgen = KeyGenerator.getInstance("AES");
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
kgen.init(128);
}
SecretKey skey = kgen.generateKey();
этот ключ передается на сервер в качестве заголовка. это Base64 кодируется с помощью этой функции:
public String secretKeyToString(SecretKey s) {
Base64 b64 = new Base64();
byte[] bytes = b64.encodeBase64(s.getEncoded());
return new String(bytes);
}
сервер тянет заголовок и делает
protected static byte[] encrypt(byte[] data, String base64encodedKey) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
Cipher cipher;
try {
cipher = Cipher.getInstance("AES");
} catch (NoSuchAlgorithmException ex) {
//log error
} catch (NoSuchPaddingException ex) {
//log error
}
SecretKey key = b64EncodedStringToSecretKey(base64encodedKey);
cipher.init(Cipher.ENCRYPT_MODE, key); //THIS IS WHERE IT FAILS
data = cipher.doFinal(data);
return data;
}
private static SecretKey b64EncodedStringToSecretKey(String base64encodedKey) {
SecretKey key = null;
try {
byte[] temp = Base64.decodeBase64(base64encodedKey.getBytes());
key = new SecretKeySpec(temp, SYMMETRIC_ALGORITHM);
} catch (Exception e) {
// Do nothing
}
return key;
}
чтобы отладить это, я ставлю точки останова после генерации ключа на стороне клиента, как раз перед шифром.init на стороне сервера. Согласно Netbeans, байты, составляющие SecretKeys, идентичны и имеют длину 16 байт (на самом деле, насколько я могу судить, объекты идентичны).
Я знаю о неограниченной силе JCE, но у меня нет впечатления, что мне это нужно для 128-битных AES.
сторона клиента: версия java "1.6.0_26"
сторона сервера: версия java "1.6.0_20"
любой Идеи?
3 ответов
я запускал ваш код по-разному, с помощью: Java 1.{5,6,7} (используя AES); различные кодеки Base64 (кодек Apache Commons, DatatypeConverted, Base64); различные наборы символов; между различными JVMs (через сокеты) ... безрезультатно. У меня нет ошибок.
чтобы сузить проблему, вы можете запустить следующий код на и заканчивается?
static {
System.out.println(System.getProperty("java.version"));
for (Provider provider : Security.getProviders())
System.out.println(provider);
}
public static void main(String[] args) throws Exception {
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(128);
SecretKey secretKey = keyGenerator.generateKey();
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
}
(Я знаю, что вы уже указали версии JDK, которые вы используете, и прочее, но это не может ранить.)
учитывая, что ключ не поврежден при передаче его с клиента на сервер (или, возможно, наоборот), то если:
- клиент бросает, но сервер не делает-ошибка находится на стороне клиента;
- клиент не бросает, но сервер делает-ошибка находится на стороне сервера;
- клиент и сервер бросает оба или ни один из них-нуждается в дальнейшем изучении.
в любом случае, если ошибка, пожалуйста, напишите весь трассировка стека где-то. Ошибка No installed provider supports this key: javax.crypto.spec.SecretKeySpec
ничего не говорит нам (по крайней мере для меня это не так, и я не смог воспроизвести эту ошибку либо).
эта ошибка может указывать на необходимость установки JCE (Java Cryptography Extension).
загрузите этот файл (или более новую версию) и скопируйте jars в JDK_FOLDER/jre / lib/security http://www.oracle.com/technetwork/pt/java/javase/downloads/jce-6-download-429243.html