cert-encoder.git

ref: f66045a6a139203cc3e9cb78e550655743c2a6f7

src/main/java/net/lulli/encrypt/pki/PkiEncryptionManager.java


  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
package net.lulli.encrypt.pki;

import net.lulli.encrypt.Pems;
import org.bouncycastle.cert.jcajce.JcaCertStore;
import org.bouncycastle.cms.*;
import org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder;
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.ContentSigner;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
import org.bouncycastle.util.Store;
import org.bouncycastle.util.encoders.Base64;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;
import java.security.cert.X509Certificate;
import java.util.ArrayList;

public class PkiEncryptionManager {
    public static final PkiEncryptionManager INSTANCE = new PkiEncryptionManager();
    private PkiEncryptionManager() {}

    public  void signFile(File fileToSign) {
        try {
            char[] password = "yourpass".toCharArray();
            String certificateAlias = "";
            String keyAlias = "";
            var keystoreFile = "full/path/to/your/original/certificate.pfx";

            Security.addProvider(new BouncyCastleProvider());
            KeyStore ks = loadKeyStore(keystoreFile, password);

            X509Certificate cert = (X509Certificate) ks.getCertificate(certificateAlias);
            PrivateKey privatekey = (PrivateKey) ks.getKey(keyAlias, password);

            String signatureFileName = fileToSign.getName().toString() + ".signature";

            byte[] buffer = loadFileIntoBuffer(fileToSign);

            byte[] signeddata = generateSignature(cert, cert.getPublicKey(), privatekey, buffer);

            writeSignatureToFile(signatureFileName, signeddata);
        } catch (Exception e) {
            throw new IllegalStateException(e.getMessage());
        }
    }

    private static byte[] loadFileIntoBuffer(File fileToSign) {
        try {
            byte[] buffer = new byte[(int) fileToSign.length()];
            try (DataInputStream in = new DataInputStream(new FileInputStream(fileToSign))) {
                in.readFully(buffer);
            }
            return buffer;
        } catch (Exception e) {
            throw new IllegalStateException(e.getMessage());
        }
    }

    private static byte[] generateSignature(X509Certificate cert, PublicKey publicKey, PrivateKey privatekey, byte[] buffer) {
        try {
            ArrayList<X509Certificate> certList = new ArrayList<X509Certificate>();
            certList.add(cert);
            Store<?> certs = new JcaCertStore(certList);
            CMSSignedDataGenerator signGen = new CMSSignedDataGenerator();

            ContentSigner sha1signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(privatekey);
            signGen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().build()).build(sha1signer, cert));
            signGen.addCertificates(certs);
            CMSTypedData content = new CMSProcessableByteArray(buffer);
            CMSSignedData signedData = signGen.generate(content, false);
            byte[] signeddata = signedData.getEncoded();
            return signeddata;
        } catch (Exception e) {
            throw new IllegalStateException(e.getMessage());
        }
    }

    public  byte[] encryptData(byte[] data, X509Certificate encryptionCertificate) {
        try {
            Security.addProvider(new BouncyCastleProvider());

            if (null != data && null != encryptionCertificate) {
                var cmsEnvelopedDataGenerator = new CMSEnvelopedDataGenerator();

                //JceKeyTransRecipientInfoGenerator jceKey = new JceKeyTransRecipientInfoGenerator(encryptionCertificate);
                cmsEnvelopedDataGenerator.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(encryptionCertificate).setProvider("BC"));
                var cmsProcessableByteArray = new CMSProcessableByteArray(data);
                var outputEncryptor = new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES256_CBC).setProvider("BC").build();
                var cmsEnvelopedData = cmsEnvelopedDataGenerator.generate(cmsProcessableByteArray, outputEncryptor);
                return cmsEnvelopedData.getEncoded();
            }
            return null;
        } catch (Exception e) {
            throw new IllegalStateException(e.getMessage());
        }
    }


    public void decryptCms(PrivateKey privateKey, byte[] encryptedData, String destinationFile) {
        try {
            var decryptedDestination = new File(destinationFile);
            //byte[] encryptedData = Files.readAllBytes(encrypted.toPath());

            var cmsEnvelopedDataParser = new CMSEnvelopedDataParser(encryptedData);

            var singleRecipient = getSingleRecipient(cmsEnvelopedDataParser);
            var jceKeyTransEnvelopedRecipient = new JceKeyTransEnvelopedRecipient(privateKey);

            try (InputStream decryptedStream = singleRecipient.getContentStream(jceKeyTransEnvelopedRecipient).getContentStream()) {
                Files.copy(decryptedStream, decryptedDestination.toPath());
            }

            System.out.println(String.format("Decrypted  to file :'%s'", decryptedDestination.getAbsolutePath()));
        } catch (Exception e) {
            throw new IllegalStateException(e.getMessage());
        }
    }

    private static RecipientInformation getSingleRecipient(CMSEnvelopedDataParser parser) {
        var recInfos = parser.getRecipientInfos().getRecipients();
        var recipientIterator = recInfos.iterator();
        if (!recipientIterator.hasNext()) {
            throw new RuntimeException("Could not find recipient");
        }
        return recipientIterator.next();
    }

    private static void writeSignatureToFile(String fileName, byte[] signeddata) {
        try {
            var fileOutputStream = new FileOutputStream(fileName);
            byte[] outputString = Base64.encode(signeddata);
            int fullLines = (int) Math.floor(outputString.length / 64);
            for (int i = 0; i < fullLines; i++) {
                fileOutputStream.write(outputString, i * 64, 64);
                fileOutputStream.write("\r\n".getBytes());
            }

            fileOutputStream.write(outputString, fullLines * 64, outputString.length % 64);
            fileOutputStream.close();
        } catch (Exception e) {
            throw new IllegalStateException(e.getMessage());
        }
    }

    private static KeyStore loadKeyStore(String keystoreFile, char[] password) {
        try {
            var keyStore = KeyStore.getInstance("PKCS12");
            keyStore.load(new FileInputStream(keystoreFile), password);
            return keyStore;
        } catch (Exception e) {
            throw new IllegalStateException(e.getMessage());
        }
    }

    /*
    public static void main(String[] args) throws Exception {
        var plainText = "this is a sample text";
        X509Certificate x509Certificate = Pems.certificateFromFile("/home/plulli/.x509crypt/local/certs/local.crt");
        //var enc = EncDec.encrypt(plainText, x509Certificate.getPublicKey().getEncoded());
        byte[] enc = encryptData(plainText.getBytes(), x509Certificate);
        System.out.printf("Cleartext: [%s]\n Encrypted: [%s]\n", plainText, new String(enc));

        Files.write(Paths.get("/tmp/output2.txt.enc"), enc);

        PrivateKey privateKey = Pems.privateKeyFromFile("/home/plulli/.x509crypt/local/certs/local.key");
        decryptCms(privateKey, enc, "/tmp/output2.txt");
    }

     */
}