【问题标题】:'No installed provider supports this key: sun.security.provider.DSAPublicKeyImpl' while using RSA encryption使用 RSA 加密时,“没有安装的提供程序支持此密钥:sun.security.provider.DSAPublicKeyImpl”
【发布时间】:2018-10-19 08:41:55
【问题描述】:

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

这是我目前的代码:

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:没有安装的提供程序支持此密钥:sun.security.provider.DSAPublicKeyImpl

虽然我使用了 RSA,但该错误提到了 DSA。 任何想法如何解决它?任何帮助将不胜感激!

【问题讨论】:

    标签: java encryption rsa keystore dsa


    【解决方案1】:

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

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

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

    What is the difference between DSA and RSA?

    【讨论】:

    • 您能否发布一个示例密钥或您使用过的 keytool 命令?请注意,“DSA”是-genkeypair的默认选项
    • 有一个命令在openssl的某处打印出证书信息,毫无疑问是使用openssl x509命令。那应该列出里面的公钥的算法。
    猜你喜欢
    • 2014-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-06
    • 2021-03-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多