Java 没有安装的提供程序支持此密钥:sun.security.rsa.RSAPublicKeyImpl,也没有这样的算法:AES/GCM/NoPadding

Java 没有安装的提供程序支持此密钥:sun.security.rsa.RSAPublicKeyImpl,也没有这样的算法:AES/GCM/NoPadding,java,encryption,rsa,Java,Encryption,Rsa,我试图创建一个密码,以便对我创建的AES密钥进行编码。我从存储公钥的文件中读取了公钥,并将其从字节转换为公钥对象。当我尝试使用此公钥初始化密码时,在cipherAES.init(cipher.ENCRYPT_模式,DecodedPublicKey)处出现错误“没有安装的提供程序支持此密钥:sun.security.rsa.RSAPublicKeyImpl” 因此,当我创建一个RSA 2048密钥生成器对象来获取提供者时,这是我在另一个程序中创建前一个密钥时使用的规范,我在Cipher ciphe

我试图创建一个密码,以便对我创建的AES密钥进行编码。我从存储公钥的文件中读取了公钥,并将其从字节转换为公钥对象。当我尝试使用此公钥初始化密码时,在
cipherAES.init(cipher.ENCRYPT_模式,DecodedPublicKey)处出现错误“没有安装的提供程序支持此密钥:sun.security.rsa.RSAPublicKeyImpl”

因此,当我创建一个RSA 2048密钥生成器对象来获取提供者时,这是我在另一个程序中创建前一个密钥时使用的规范,我在
Cipher cipherAES=Cipher.getInstance(“AES/GCM/NoPadding”,kpgenProv.getName())处得到错误“No-this-algorithm:AES/GCM/NoPadding”

我需要使用转换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();```

JavaJDK通常与一些负责加密操作的安全提供者一起提供。由于历史原因,它们没有合并/捆绑,而是存在于彼此之下。如果您通过实例化Java来选择一个算法,那么您将发现哪个提供者“负责”这个算法,并接受他

另一方面,如果您喜欢使用特定的提供程序,则可以在实例化过程中命名该提供程序(这就是您对第二个参数“kpgenProv.getName”所做的操作):

正如您在我的简单程序中所看到的,对于“RSA”和“AES/GCM/NoPadding”,有两种不同的提供程序,但当强制使用特定的提供程序时,您会收到“未安装提供程序支持…”异常

因此,通常您会忽略提供者名称,让Java为该算法选择“最佳”提供者

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

代码:


我发现将转换添加为“RSA”可以让一切都正常工作,删除了提供程序。这会删除转换AES/GCM,但这仍然是一种有效的方法吗?不过,我看到了当我没有给它提供提供程序并将其保留为Cipher cipherAES=Cipher.getInstance(“AES/GCM/NoPadding”)时遇到的问题;这就是我使用cipheres.init(Cipher.ENCRYPT_模式,decodedPublicey)的时候吗,它抱怨我没有安装正确的提供程序,没有安装的提供程序支持此密钥:sun.security.rsa.RSAPublicKeyImpl,我需要导入什么吗?我正在从字节创建密钥,但密钥不是空的,所以我认为这不是问题。当我将AES/GCM/NoPadding更改为rsa时,它突然正常工作,没有任何错误,b但我仍然希望转换为AES-GCM,因此我认为这不是问题。这可能是我使用的IDE的问题吗?我的答案是针对问题中的“无提供程序”部分。是否尝试运行混合加密?然后需要(随机)加密使用RSA加密算法生成AES GCM密钥。您的程序存在AES GCM密码的输入是公钥的问题-这不起作用。搜索“java AES GCM RSA混合加密”,您将找到许多示例。好的,可以!感谢帮助!
Cipher.getInstance("AES/GCM/NoPadding", kpgenProv.getName())
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());
    }
}