'使用RSA加密时,没有安装的提供程序支持此密钥:sun.security.provider.DSAPublicKeyImpl'

时间:2018-05-09 09:23:16

标签: java encryption rsa keystore dsa

我正在尝试使用我生成的密钥加密文本文件。 现在我应该用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

错误提及DSA,尽管我使用了RSA。 任何想法如何解决?任何帮助将不胜感激!

1 个答案:

答案 0 :(得分: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?