如何从我们创建的密钥库中检索我的公钥和私钥

我的任务如下:

  • 从我创建的密钥库中检索我的公钥和私钥。
  • 使用这些密钥使用我的RSA 2048位公钥对段落进行加密。
  • 使用DSA-SHA-1签名算法对结果进行数字签名。
  • 将数字签名输出保存在名为output.dat的文件中。
  • 下面的程序抛出错误:“java.security.InvalidKeyException:没有安装的提供者支持这个键:sun.security.provider.DSAPublicKeyImpl”。

    import java.security.*;
    import java.security.KeyStore.*;
    import java.io.*;
    import java.security.PublicKey;
    import java.security.PrivateKey;
    import javax.crypto.Cipher;
    import java.nio.charset.*;
    import sun.security.provider.*;
    import  javax.crypto.*;
    
    public class Code {
    
    /**
     * @param args the command line arguments
     */
        public static void main(String[] args) {
    
            try {
    
                /* getting data for keystore */
    
                File file = new File(System.getProperty("user.home") + File.separatorChar + ".keystore");
                FileInputStream is = new FileInputStream(file);
                KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
    
                /*Information for certificate to be generated */ 
                String password = "abcde";
                String alias = "mykeys";
                String alias1 = "skeys";
    
                String filepath ="C:email.txt";
    
                /* getting the key*/
                keystore.load(is, password.toCharArray());
                PrivateKey key = (PrivateKey)keystore.getKey(alias, "bemylife".toCharArray());
                //PrivateKey key = cert1.getPrivateKey();
                //PublicKey key1= (PrivateKey)key;
    
                /* Get certificate of public key */
                java.security.cert.Certificate cert = keystore.getCertificate(alias); 
    
                /* Here it prints the public key*/
                System.out.println("Public Key:");
                System.out.println(cert.getPublicKey());
    
                /* Here it prints the private key*/
                System.out.println("nPrivate Key:");
                System.out.println(key);
    
                Cipher cipher = Cipher.getInstance("RSA");
                cipher.init(Cipher.ENCRYPT_MODE,cert.getPublicKey());
    
                String cleartextFile = "C:email.txt";
                String ciphertextFile = "D:ciphertextRSA.png";
    
                FileInputStream fis = new FileInputStream(cleartextFile);
                FileOutputStream fos = new FileOutputStream(ciphertextFile);
                CipherOutputStream cos = new CipherOutputStream(fos, cipher);
    
                byte[] block = new byte[32];
                int i;
                while ((i = fis.read(block)) != -1) {
                    cos.write(block, 0, i);
                }
                cos.close();
    
    
                /* computing the signature*/
                Signature dsa = Signature.getInstance("SHA1withDSA", "SUN");
                dsa.initSign(key);
                FileInputStream f = new FileInputStream(ciphertextFile);
                BufferedInputStream in = new BufferedInputStream(f);
                byte[] buffer = new byte[1024];
                int len;
                while ((len = in.read(buffer)) >= 0) {
                   dsa.update(buffer, 0, len);
               };
               in.close();
    
               /* Here it prints the signature*/
               System.out.println("Digital Signature :");
               System.out.println( dsa.sign());
    
               /* Now Exporting Certificate */
               System.out.println("Exporting Certificate. ");
               byte[] buffer_out = cert.getEncoded();
               FileOutputStream os = new FileOutputStream(new File("d:signedcetificate.cer"));
               os.write(buffer_out);
               os.close();
    
               /* writing signature to output.dat file */
               byte[] buffer_out1 = dsa.sign();
               FileOutputStream os1 = new FileOutputStream(new File("d:output.dat"));
               os1.write(buffer_out1);
               os1.close();
    
           } catch (Exception e) {System.out.println(e);}
    
       }
    }
    

    问题是DSA密钥不适合RSA加密。 您需要一个RSA密钥进行加密,也许您可​​以将签名算法切换到RSA / SHA1以避免需要两个密钥。


    您必须从keystore文件(可能以.jks结尾)将其读取到java.security.KeyStore对象中。

    /**
     * Reads a Java keystore from a file.
     * 
     * @param keystoreFile
     *          keystore file to read
     * @param password
     *          password for the keystore file
     * @param keyStoreType
     *          type of keystore, e.g., JKS or PKCS12
     * @return the keystore object
     * @throws KeyStoreException
     *           if the type of KeyStore could not be created
     * @throws IOException
     *           if the keystore could not be loaded
     * @throws NoSuchAlgorithmException
     *           if the algorithm used to check the integrity of the keystore
     *           cannot be found
     * @throws CertificateException
     *           if any of the certificates in the keystore could not be loaded
     */
    public static KeyStore loadKeyStore(final File keystoreFile,
        final String password, final String keyStoreType)
        throws KeyStoreException, IOException, NoSuchAlgorithmException,
        CertificateException {
      if (null == keystoreFile) {
        throw new IllegalArgumentException("Keystore url may not be null");
      }
      LOG.debug("Initializing key store: {}", keystoreFile.getAbsolutePath());
      final URI keystoreUri = keystoreFile.toURI();
      final URL keystoreUrl = keystoreUri.toURL();
      final KeyStore keystore = KeyStore.getInstance(keyStoreType);
      InputStream is = null;
      try {
        is = keystoreUrl.openStream();
        keystore.load(is, null == password ? null : password.toCharArray());
        LOG.debug("Loaded key store");
      } finally {
        if (null != is) {
          is.close();
        }
      }
      return keystore;
    }
    

    一旦拥有KeyStore ,您就可以访问Certificate以及公钥和私钥。

    但是使用它来签署文本并将其保存在文件中更为复杂,并且容易出错。 使用给定的公钥查看Sign字符串,并将getKeyPair方法替换为使用KeyStore 。 一些东西沿着

    public static KeyPair getKeyPair(final KeyStore keystore, 
        final String alias, final String password) {
      final Key key = (PrivateKey) keystore.getKey(alias, password.toCharArray());
    
      final Certificate cert = keystore.getCertificate(alias);
      final PublicKey publicKey = cert.getPublicKey();
    
      return KeyPair(publicKey, (PrivateKey) key);
    }
    

    (显然有点粗糙,我没有样品)


    我没有将Java代码存储在我的大脑顶部,但是一些普遍的理智检查是:

  • 你想存储的公共证书是你想要的吗? 特别是,我的回忆是,带有公钥和私钥的证书一起存储在一个别名下,因此您在那里设置的两个别名设置看起来很奇怪。 尝试将两者存储在相同的别名下,并在私钥和公钥调用中引用它们。

  • 你能否从证书中得到其他任何东西 - 例如,主题DN或颁发者DN都是证书中必备的字段。 这给了你一个很好的证明,即正在按照预期读取证书。

  • 在几乎任何加密交易中,要非常小心地阅读文件并传输编码方法。 如果您创建了文件IO并以奇怪的方式从文件IO中拉出,则可能会破坏密钥材料的编码。 这是最后一件要检查的事情 - 通常Java和JKS对此并没有那么糟糕,但它发生了。 同样,要清楚文件的格式 - 例如,JKS文件与PKCS 12文件不同。

  • 链接地址: http://www.djcxy.com/p/75571.html

    上一篇: How to retrieve my public and private key from the keystore we created

    下一篇: implementing a shell in C