【问题标题】:No installed provider supports this key: sun.security.rsa.RSAPublicKeyImpl and No such algorithm: AES/GCM/NoPadding没有安装的提供程序支持这个密钥:sun.security.rsa.RSAPublicKeyImpl 和没有这样的算法:AES/GCM/NoPadding
【发布时间】:2021-03-11 21:34:13
【问题描述】:

我正在尝试创建一个密码来对我创建的 AES 密钥进行编码。我从存储公钥的文件中读取了公钥,并将其从字节转换为公钥对象。当我尝试使用此公钥初始化密码时,在 cipherAES.init(Cipher.ENCRYPT_MODE, DecodedPublicKey);

收到错误消息“没有安装的提供程序支持此密钥:sun.security.rsa.RSAPublicKeyImpl”

因此,当我创建 RSA 2048 密钥生成器对象以获取提供程序时,这是我用于在另一个程序中创建上一个密钥的规范,我收到错误“没有这样的算法:AES/GCM/NoPadding”在Cipher cipherAES = Cipher.getInstance("AES/GCM/NoPadding", kpgenProv.getName());

我需要使用转换 AES/GCM/NoPadding,从 .getProvider 提供的提供者似乎是正确的,即 SunRsaSign。有人对这个问题有任何见解吗?没有提供者时它识别转换正常,但有提供者时拒绝它。

      String pubAlgo = publicKeyScanner.nextLine(); // not used
      String PublicKey = publicKeyScanner.nextLine(); // this will stop when it hits a newline and the encoded key may have the newline char value causing the private key to be piecemeal
      byte[] decodedPublicKey = Base64.getDecoder().decode(PublicKey);
      KeyFactory kf = KeyFactory.getInstance("RSA"); // or "EC" or whatever
      PublicKey DecodedPublicKey = kf.generatePublic(new X509EncodedKeySpec(decodedPublicKey));
      publicKeyScanner.close();
      System.out.println(DecodedPublicKey.toString());
    
      KeyGenerator keyGen = KeyGenerator.getInstance("AES");
      keyGen.init(128); // for example
      SecretKey AESKey = keyGen.generateKey();

      KeyPairGenerator kpgen = KeyPairGenerator.getInstance("RSA");
      kpgen.initialize(2048);
      Provider kpgenProv = kpgen.getProvider();
      System.out.println(kpgenProv.getName());
      Cipher cipherAES = Cipher.getInstance("AES/GCM/NoPadding", kpgenProv.getName());
      cipherAES.init(Cipher.ENCRYPT_MODE, DecodedPublicKey);
      byte[] AESKEYBYTES = AESKey.getEncoded();```

【问题讨论】:

  • 我发现添加转换为“RSA”可以使一切正常,删除提供程序。虽然这消除了转换 AES/GCM,这仍然是一种有效的方式吗?

标签: java encryption rsa


【解决方案1】:

Java JDK 通常与一些负责加密操作的安全提供程序一起交付。由于历史原因,它们没有被合并/捆绑,而是存在于彼此之下。如果你通过实例化Java来选择一个算法,会找出哪个提供者对这个算法“负责”并接受他。

另一方面 - 如果您想使用特定的提供者,您可以在实例化期间命名提供者(这就是您使用第二个参数“kpgenProv.getName”所做的:

Cipher.getInstance("AES/GCM/NoPadding", kpgenProv.getName())

正如您在我的简单程序中看到的那样,“RSA”和“AES/GCM/NoPadding”有两个不同提供程序,但是当强制使用特定提供程序时,您会收到“未安装的提供程序-支持...”异常。

所以通常你会省略提供者的名称,让 Java 为这个算法选择“最佳”提供者。

我的系统上的输出(OpenJDK11):

Get security provider
provider for RSA encryption: SunRsaSign version 11
provider for AES/GCM/NoPadding: SunJCE version 11

代码:

import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;

public class Main {
    public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchPaddingException {
        System.out.println("Get security provider");

        KeyFactory kf = KeyFactory.getInstance("RSA");
        System.out.println("provider for RSA encryption: " + kf.getProvider());

        Cipher cipherAES = Cipher.getInstance("AES/GCM/NoPadding");
        System.out.println("provider for AES/GCM/NoPadding: " + cipherAES.getProvider());
    }
}

【讨论】:

  • 我看到了,但是,当我不给它提供者并将其保留为 Cipher cipherAES = Cipher.getInstance("AES/GCM/NoPadding");是当我去使用 cipherAES.init(Cipher.ENCRYPT_MODE, DecodedPublicKey) 时,它抱怨我没有安装正确的提供程序,没有安装的提供程序支持这个密钥:sun.security.rsa.RSAPublicKeyImpl,我需要导入什么东西?
  • 我正在从字节创建密钥,但密钥不为空,所以我认为这不是问题。当我将 AES/GCM/NoPadding 更改为 RSA 时,它突然可以正常工作,但我仍然希望转换为 AES-GCM,所以我认为这不是问题。这可能是我正在使用的 IDE 的问题吗?
  • 我的回答是针对您问题的“无提供者”部分。您是否尝试运行混合加密?然后,您需要使用 RSA 加密算法加密(随机)生成的 AES GCM 密钥。您的程序存在 AES GCM 密码的输入是公钥的问题 - 这不起作用。搜索“java aes gcm rsa 混合加密”,你会发现很多例子。
  • 好的,会的!感谢您的帮助!
猜你喜欢
  • 2021-11-23
  • 1970-01-01
  • 1970-01-01
  • 2018-10-19
  • 2014-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-09
相关资源
最近更新 更多