Java AES:没有安装的提供程序支持此密钥:javax.crypto.spec.SecretKeySpec

发布于 2024-12-19 04:35:14 字数 1831 浏览 0 评论 0原文

我正在尝试设置 128 位 AES 加密,但在 Cipher.init 上抛出异常:

没有安装的提供程序支持此密钥: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;
}

为了调试此功能,我在客户端的密钥生成之后和服务器端的 cipher.init 之前放置了断点。根据 Netbeans 的说法,组成 SecretKey 的字节是相同的,长度为 16 个字节(事实上,据我所知,这些对象是相同的)。

我知道 JCE 的强度无限,但我并不认为 128 位 AES 需要它。

客户端:java 版本“1.6.0_26”

服务器端:java 版本“1.6.0_20”

有什么想法吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

墟烟 2024-12-26 04:35:14

我以不同的方式运行您的代码,使用:Java 1.{5,6,7}(使用 AES);不同的 Base64 编解码器(Apache Commons Codec、DatatypeConverted、Base64);不同的字符集;在不同的 JVM 之间(通过套接字)……无济于事。我没有任何错误。

为了缩小问题范围,您可以在两端运行以下代码吗?

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 版本等内容,但这不会有什么坏处。)

考虑到密钥在从客户端传输到客户端时不会被损坏服务器(或者可能相反),那么如果:

  • 客户端抛出,但服务器没有——错误在客户端;
  • 客户端不会抛出异常,但服务器会抛出异常——错误在服务器端;
  • 客户端和服务器都抛出或都不抛出 - 需要进一步调查。

无论如何,如果抛出错误,请将整个堆栈跟踪发布到某处。错误 没有安装的提供程序支持此密钥:javax.crypto.spec.SecretKeySpec 没有告诉我们任何信息(至少对我来说没有,而且我也无法重现此特定错误)。

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).

酷到爆炸 2024-12-26 04:35:14

此错误可能表明您需要安装 JCE(Java 加密扩展)。

下载此文件(或更新版本)并将 jar 复制到 JDK_FOLDER/jre/lib/security
http://www.oracle.com /technetwork/pt/java/javase/downloads/jce-6-download-429243.html

This error could indicate that you need to install JCE (Java Cryptography Extension).

Download this file (or newer version) and copy jars to JDK_FOLDER/jre/lib/security
http://www.oracle.com/technetwork/pt/java/javase/downloads/jce-6-download-429243.html

当梦初醒 2024-12-26 04:35:14

当我向 SecretKeySpec 构造函数提供不正确的密钥时,就会发生此错误。

This error happens with me, when providing an incorrect key to SecretKeySpec constructor.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文