問題描述
我正在嘗試設置 128 位 AES 加密,但我的 Cipher.init 出現異常:
沒有安裝的提供者支持這個密鑰:javax.crypto.spec.SecretKeySpec
我正在使用以下代碼在客戶端生成密鑰:
私鑰生成器 kgen;嘗試 {kgen = KeyGenerator.getInstance("AES");} 捕捉(NoSuchAlgorithmException e){//TODO 自動生成的 catch 塊e.printStackTrace();}kgen.init(128);}SecretKey skey = kgen.generateKey();
然后,此密鑰作為標頭傳遞給服務器.它是使用此函數進行 Base64 編碼的:
public String secretKeyToString(SecretKey s) {Base64 b64 = 新 Base64();byte[] bytes = b64.encodeBase64(s.getEncoded());返回新字符串(字節);}
服務器拉頭,然后做
protected static byte[] encrypt(byte[] data, String base64encodedKey) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException {密碼密碼;嘗試 {cipher = Cipher.getInstance("AES");} 捕捉(NoSuchAlgorithmException ex){//記錄錯誤} 捕捉(NoSuchPaddingException 前){//記錄錯誤}SecretKey 密鑰 = b64EncodedStringToSecretKey(base64encodedKey);cipher.init(Cipher.ENCRYPT_MODE,密鑰);//這是失敗的地方數據 = cipher.doFinal(data);返回數據;}私有靜態 SecretKey b64EncodedStringToSecretKey(String base64encodedKey) {密鑰密鑰 = 空;嘗試 {byte[] temp = Base64.decodeBase64(base64encodedKey.getBytes());密鑰 = 新的 SecretKeySpec(臨時,SYMMETRIC_ALGORITHM);} 捕捉(異常 e){//沒做什么}返回鍵;}
為了調試它,我在客戶端的密鑰生成之后和服務器端的 cipher.init 之前都放置了斷點.根據 Netbeans 的說法,組成 SecretKey 的字節是相同的,長度為 16 個字節(事實上,據我所知,對象是相同的).
我知道無限強度的 JCE 東西,但我并不認為我需要它來實現 128 位 AES.
客戶端:java版本1.6.0_26"
服務器端:java 版本1.6.0_20"
有什么想法嗎?
我以不同的方式運行您的代碼,包括:Java 1.{5,6,7}(使用 AES);不同的 Base64 編解碼器(Apache Commons Codec、DatatypeConverted、Base64);不同的字符集;在不同的 JVM 之間(通過套接字) …無濟于事.我沒有錯誤.
為了縮小問題范圍,您可以在兩端運行以下代碼嗎?
靜態{System.out.println(System.getProperty("java.version"));對于(提供者提供者:Security.getProviders())System.out.println(提供者);}公共靜態 void main(String[] args) 拋出異常 {KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");keyGenerator.init(128);SecretKey secretKey = keyGenerator.generateKey();密碼密碼 = Cipher.getInstance("AES");cipher.init(Cipher.ENCRYPT_MODE,secretKey);}
(我知道您已經說明了您正在使用的 JDK 版本等內容,但不會有什么壞處.)
鑒于在您將密鑰從客戶端傳輸到服務器(或者可能是反向傳輸)時密鑰沒有損壞,那么如果:
- 客戶端拋出,但服務器沒有——錯誤在客戶端;
- 客戶端不會拋出,但服務器會拋出——錯誤在服務器端;
- 客戶端和服務器都拋出或都不拋出——需要進一步調查.
在任何情況下,如果拋出錯誤,請將整個堆棧跟蹤發布到某處.錯誤 No installed provider supports this key: javax.crypto.spec.SecretKeySpec
告訴我們什么都沒有(至少對我來說沒有,而且我也無法重現這個特定的錯誤).p>
I'm trying to set up 128 bit AES encryption, and I'm getting an exception thrown on my Cipher.init:
No installed provider supports this key: javax.crypto.spec.SecretKeySpec
I'm generating the Key on the client side using the following code:
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();
This key is then passed to the server as a header. it is Base64 encoded using this function:
public String secretKeyToString(SecretKey s) {
Base64 b64 = new Base64();
byte[] bytes = b64.encodeBase64(s.getEncoded());
return new String(bytes);
}
The server pulls the header, and does
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;
}
To debug this, I put breakpoints after both the key generation on the client side, and just before the cipher.init on the server side. According to Netbeans, the bytes that make up the SecretKeys are identical and are 16 bytes in length (In fact, as far as I can tell, the objects are identical).
I am aware of the unlimited strength JCE stuff, but I'm not under the impression I needed it for 128 bit AES.
Client Side: java version "1.6.0_26"
Server Side: java version "1.6.0_20"
Any Ideas?
I've run your code in different ways, with: Java 1.{5,6,7} (using AES); different Base64 codecs (Apache Commons Codec, DatatypeConverted, Base64); different character sets; between different JVMs (through sockets) … to no avail. I got no errors.
To narrow down the problem, can you run the following code on both ends?
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);
}
(I know that you've already stated the JDK versions you're using and stuff, but it can't hurt.)
Given that the key doesn't get corrupted while you transfer it from client to server (or maybe in reverse), then if:
- the client throws, but the server doesn't—the error is on the client side;
- the client doesn't throw, but the server does—the error is on the server side;
- the client and server both throws or neither of them—needs further investigation.
In any case, if an error is thrown, please post the whole stack trace somewhere. The error No installed provider supports this key: javax.crypto.spec.SecretKeySpec
tells us nothing (at least for me it doesn't, and I couldn't reproduce this particular error either).
這篇關于Java AES:沒有安裝的提供程序支持此密鑰:javax.crypto.spec.SecretKeySpec的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!