【问题标题】:Java AES: No installed provider supports this key: javax.crypto.spec.SecretKeySpecJava AES:没有安装的提供程序支持此密钥:javax.crypto.spec.SecretKeySpec
【发布时间】:2018-04-19 21:18:19
【问题描述】:

我正在尝试设置 128 位 AES 加密,但我的 Cipher.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;
}

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

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

客户端:java版本“1.6.0_26”

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

有什么想法吗?

【问题讨论】:

  • 您在服务器上安装了哪些提供程序? for (Provider p : Security.getProviders()) System.out.println(p.getName());
  • 还有,SYMMETRIC_ALGORITHM的定义是什么?
  • @erickson Dangit,我尝试替换 SYMMETRIC_ALGORITHM 字符串。它们是定义为“AES”的最终字符串(在服务器和客户端上)。我会尝试您提供给我的提供程序代码并回复您
  • @erickson 输出:SUN SunRsaSign SunJSSE SunJCE SunJGSS SunSASL XMLDSig SunPCSC SunPKCS11-NSS
  • 您是否从 Oracle 安装了无限制加密的策略文件?您可以尝试安装它们吗?

标签: java encryption cryptography aes secret-key


【解决方案1】:

我以不同的方式运行您的代码,包括: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 版本等内容,但不会有什么坏处。)

鉴于在您将密钥从客户端传输到服务器(或者可能是反向传输)时密钥没有损坏,那么如果:

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

在任何情况下,如果抛出错误,请将整个堆栈跟踪发布到某处。错误No installed provider supports this key: javax.crypto.spec.SecretKeySpec 什么也没告诉我们(至少对我来说没有,而且我也无法重现这个特定的错误)。

【讨论】:

  • 对不起。我似乎很久以前就问过这个问题……从那时起,问题就解决了。虽然我不记得您的答案是解决方案的一部分……但它仍然是一个很好的答案。感谢您的帮助:)
  • @CodyS 您实际上还忘记了您已经在问题的评论部分做出了类似的回复这一事实。 :D 没什么大不了的!
  • 我有同样的问题,你的代码我得到了同样的错误。虽然我正在尝试使用 AES_192/GCM/NoPadding。
  • @Thayne 好吧,仅凭您提供的信息很难判断。哪个JDK?哪个平台? 确切的错误是什么?您使用的确切代码是什么?
【解决方案2】:

此错误可能表明您需要安装 JCE(Java Cryptography Extension)。

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-19
      • 2014-11-30
      • 2021-03-11
      • 1970-01-01
      • 2012-12-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多