java - 使用 RSA 加密时,“没有安装的提供程序支持此 key : sun. security.provider.DSAPublicKeyImpl”

标签 java encryption rsa keystore dsa

我正在尝试使用我生成的 key 加密文本文件。 现在我应该使用 RSA 算法加密这个 key ,使用最终将接收加密数据的一方的公钥。

这是我到目前为止的代码:

package cryptogaphy;


import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;

import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.cert.Certificate;
import java.security.KeyPair;
import java.security.Key;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;



public class trythree {

public static void main(String[] args) throws Exception {

    try {

    // Generate a symmetric key
    KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
    SecureRandom secureRandom = new SecureRandom();
    int keyBitSize = 128;
    keyGenerator.init(keyBitSize, secureRandom);
    SecretKey symmetricKey = keyGenerator.generateKey();
    Key key = symmetricKey;

    // Generate random IV
    byte[] ivBytes = new byte[16];
    IvParameterSpec iv = new IvParameterSpec(ivBytes);

    System.out.println("Random Iv: " + iv);

    // File Encryption
    FileInputStream fis = new FileInputStream("C:\\Users\\Victoria\\Desktop\\plainData.txt");
    FileOutputStream fos = new FileOutputStream("C:\\Users\\Victoria\\Desktop\\encryptedData.txt");

    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

    cipher.init(Cipher.ENCRYPT_MODE, key, iv, SecureRandom.getInstance("SHA1PRNG"));
    CipherInputStream cis = new CipherInputStream(fis, cipher);
    write(cis, fos);


    // load Alice's keystore - input method should be changed
    char[] aliceStorePass = "123456".toCharArray();
    char[] aliceKeypass = "aliceKey".toCharArray();

    FileInputStream aliceInput = new FileInputStream("C:\\Users\\Victoria\\Desktop\\aliceKeystore.jks");
    KeyStore aliceKeystore = KeyStore.getInstance("JKS");
    aliceKeystore.load(aliceInput, aliceStorePass);

    String alias = "alice";
    String alias2 = "bobcert";

    Key aliceKey = aliceKeystore.getKey(alias, aliceKeypass);
    PublicKey bobPublicKey = null;

    // retrieve Alice's private key and Bob's public key from Alice's keystore
    if (aliceKey instanceof PrivateKey) {
      Certificate cert = aliceKeystore.getCertificate(alias2);
      bobPublicKey = cert.getPublicKey();
      new KeyPair(bobPublicKey, (PrivateKey) aliceKey);
      System.out.println((PrivateKey) aliceKey);
    }
    System.out.println("Bob's public key: " + bobPublicKey);

    // Encrypt the Symmetric Key with asymmetric RSA algorithm
    byte[] encryptedkey = symmetricKey.getEncoded();
    Cipher keyCipher = Cipher.getInstance("RSA");  
    keyCipher.init(Cipher.ENCRYPT_MODE, bobPublicKey );  
    keyCipher.doFinal(encryptedkey);

    System.out.println("Asymmetric Secret Key: " + encryptedkey);
    System.out.println("Symmetric Key: " + key);



} catch (KeyStoreException | NoSuchAlgorithmException | UnrecoverableKeyException | CertificateException e){
System.out.println(e); 
}

    }



    private static void write(InputStream in, OutputStream out) throws IOException {
        byte[] buf = new byte[64];
        int numOfBytesRead;
        while((numOfBytesRead = in.read(buf))!=-1)
             {
                 out.write(buf, 0 ,numOfBytesRead);
             }     
           out.close();
           in.close();  
           System.out.println("-----ENCRYPTION COMPLETED!-----");
    }
}

现在,我收到此错误 -

java.security.InvalidKeyException:没有安装的提供程序支持此 key :sun.security.provider.DSAPublicKeyImpl

尽管我使用了 RSA,但该错误提到了 DSA。 有什么想法如何解决吗?任何帮助将不胜感激!

最佳答案

看来bobPublicKey是DSA key ,DSA不能用于加密,只能用于数字签名。

Cipher init 失败,因为无法使用 DSA key 执行 RSA 加密(错误消息表明没有加密提供程序支持它)

Cipher keyCipher = Cipher.getInstance("RSA");  
keyCipher.init(Cipher.ENCRYPT_MODE, bobPublicKey );  

参见What is the difference between DSA and RSA?

关于java - 使用 RSA 加密时,“没有安装的提供程序支持此 key : sun. security.provider.DSAPublicKeyImpl”,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50249825/

相关文章:

java - 在 JLabel 中逐字母显示字符串 "animation"?

java - Java 中的两条腿 OAuth2 示例?

java - Apache Karaf 是否处理任何 JAR 或 WAR 的热部署?

php - MySQL 查询返回带有 AES_ENCRYPT 的空白字段

certificate - ASN1。序列 vs 集合

Java程序在所有行中添加双引号

cocoa - 将数据写入Cocoa文件?

c++ - 使用 C++、Openssl 和 aes 加密和解密字符串

c# - 如何在 .NET 中验证 RSA-SHA512 XML 签名?

ruby - 使用安全转换验证使用 Ruby/OpenSSL 创建的 RSA 签名