openssl -decrypt by Java

前端 未结 2 894
粉色の甜心
粉色の甜心 2021-02-11 10:06

all! I am trying to resolve the issue.

I have bat-file with command:

openssl smime -decrypt -binary -inform DER -recip [path to certificate] -inkey  [pat         


        
2条回答
  •  粉色の甜心
    2021-02-11 10:58

    I've found the solution for my question! Thank you all for your advises.

    I've found the source. Thank you very much to author of this source.

    I implemented it that way:

    package javatest;
    
    import org.bouncycastle.cms.*;
    import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder;
    import org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient;
    import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator;
    import org.bouncycastle.jce.provider.BouncyCastleProvider;
    import org.bouncycastle.operator.OutputEncryptor;
    
    import java.io.*;
    import java.nio.file.Files;
    import java.security.*;
    import java.security.cert.CertificateEncodingException;
    import java.security.cert.CertificateException;
    import java.security.cert.CertificateFactory;
    import java.security.cert.X509Certificate;
    import java.util.Collection;
    import java.util.Enumeration;
    import java.util.Iterator;
    
    /**
     *
     * @author kagkarlsson
     * @link https://github.com/kagkarlsson/cms-decrypt-example/blob/master/src/main/java/no/posten/dpost/EncryptAndDecrypt.java
     */
    public class EncryptAndDecrypt {
        public static void decrypt(PrivateKey privateKey, File encrypted, File decryptedDestination) throws IOException, CMSException {
            byte[] encryptedData = Files.readAllBytes(encrypted.toPath());
    
            CMSEnvelopedDataParser parser = new CMSEnvelopedDataParser(encryptedData);
    
            RecipientInformation recInfo = getSingleRecipient(parser);
            Recipient recipient = new JceKeyTransEnvelopedRecipient(privateKey);
    
            try (InputStream decryptedStream = recInfo.getContentStream(recipient).getContentStream()) {
                Files.copy(decryptedStream, decryptedDestination.toPath());
            }
    
            System.out.println(String.format("Decrypted '%s' to '%s'", encrypted.getAbsolutePath(), decryptedDestination.getAbsolutePath()));
        }
    
        public static void encrypt(X509Certificate cert, File source, File destination) throws CertificateEncodingException, CMSException, IOException {
            CMSEnvelopedDataStreamGenerator gen = new CMSEnvelopedDataStreamGenerator();
            gen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(cert));
            OutputEncryptor encryptor = new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES256_CBC).setProvider(BouncyCastleProvider.PROVIDER_NAME).build();
    
            try (FileOutputStream fileStream = new FileOutputStream(destination);
                    OutputStream encryptingStream = gen.open(fileStream, encryptor)) {
    
                byte[] unencryptedContent = Files.readAllBytes(source.toPath());
                encryptingStream.write(unencryptedContent);
            }
    
            System.out.println(String.format("Encrypted '%s' to '%s'", source.getAbsolutePath(), destination.getAbsolutePath()));
        }
    
        public static X509Certificate getX509Certificate(File certificate) throws IOException, CertificateException {
            try (InputStream inStream = new FileInputStream(certificate)) {
                CertificateFactory cf = CertificateFactory.getInstance("X.509");
                return (X509Certificate) cf.generateCertificate(inStream);
            }
        }
    
        public static PrivateKey getPrivateKey(File file, String password) throws Exception {
            KeyStore ks = KeyStore.getInstance("PKCS12");
            try (FileInputStream fis = new FileInputStream(file)) {
                ks.load(fis, password.toCharArray());
            }
    
            Enumeration aliases = ks.aliases();
            String alias = aliases.nextElement();
            return (PrivateKey) ks.getKey(alias, password.toCharArray());
        }
    
        private static RecipientInformation getSingleRecipient(CMSEnvelopedDataParser parser) {
            Collection recInfos = parser.getRecipientInfos().getRecipients();
            Iterator recipientIterator = recInfos.iterator();
            if (!recipientIterator.hasNext()) {
                throw new RuntimeException("Could not find recipient");
            }
            return (RecipientInformation) recipientIterator.next();
        }
    }

    and

    package javatest;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.InputStreamReader;
    import java.nio.file.Files;
    import java.security.PrivateKey;
    import java.security.Security;
    import org.bouncycastle.jce.provider.BouncyCastleProvider;
    import org.bouncycastle.openssl.PEMKeyPair;
    import org.bouncycastle.openssl.PEMParser;
    import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
    
    /**
     * Test decrypt file
     *
     * @author a.chernyy
     */
    public class JavaTest {
    
        /**
         * String to hold name of the encryption algorithm.
         */
        public static final String ALGORITHM = "RSA";
    
        /**
         * String to hold the path to the keys' dir.
         */
        public static final String KEYS_DIR = "D:" + File.separator + "keystore" + File.separator;
    
        /**
         * String to hold the name of the private key file.
         */
        public static final String PRIVATE_KEY_FILE = KEYS_DIR + "priv.key";
    
        /**
         * String to hold name of the public key file.
         */
        public static final String CERT_FILE = KEYS_DIR + "cert.cer";
    
        /**
         * String to hold name of the encrypted file.
         */
        public static final String ENCRYPTED_FILE = "D:" + File.separator + "Temp" + File.separator + "encrypted.xml";
    
        /**
         * String to hold name of the decrypted file.
         */
        public static final String DECRYPTED_FILE = "D:" + File.separator + "Temp" + File.separator + "decrypted.xml";
    
        /**
         * @param args the command line arguments
         */
        public static void main(String[] args) {
            try {
                //get private key
                File keyFl = new File(PRIVATE_KEY_FILE);
                Security.addProvider(new BouncyCastleProvider());
                PEMParser pemParser = new PEMParser(new InputStreamReader(new FileInputStream(keyFl)));
                PEMKeyPair pemKeyPair = (PEMKeyPair) pemParser.readObject();
                JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
                PrivateKey privateKey = converter.getPrivateKey(pemKeyPair.getPrivateKeyInfo());
                
                //Decrypt file
                File encryptedFile = new File(ENCRYPTED_FILE);
                File decryptedFile = new File(DECRYPTED_FILE);
                Files.deleteIfExists(decryptedFile.toPath());
                Security.addProvider(new BouncyCastleProvider());
                EncryptAndDecrypt.decrypt(privateKey, encryptedFile, decryptedFile);
            } catch (Exception e) {
                System.out.println("It's a pity...");
                System.err.println(e.getMessage());
            }
            System.out.println("THE END");
        }
    
    }

    So, it works! :)

提交回复
热议问题