All Downloads are FREE. Search and download functionalities are using the official Maven repository.

no.difi.asic.SignatureHelper Maven / Gradle / Ivy

Go to download

Generic implementation of ASiC-E archives in accordance with ETSI 102 918 v1.3.1.

The newest version!
package no.difi.asic;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.Provider;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.Arrays;

import org.bouncycastle.cert.jcajce.JcaCertStore;
import org.bouncycastle.cms.CMSProcessableByteArray;
import org.bouncycastle.cms.CMSSignedData;
import org.bouncycastle.cms.CMSSignedDataGenerator;
import org.bouncycastle.cms.SignerInfoGenerator;
import org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.DigestCalculatorProvider;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.io.BaseEncoding;


/**
 * Helper class to assist when creating a signature.
 * 

* Not thread safe * * @author steinar * Date: 11.07.15 * Time: 22.53 */ public class SignatureHelper { private static final Logger logger = LoggerFactory.getLogger(SignatureHelper.class); public static final KeyStoreType DEFAULT_KEY_STORE_TYPE = KeyStoreType.JKS; protected final Provider provider; protected final JcaDigestCalculatorProviderBuilder jcaDigestCalculatorProviderBuilder; protected X509Certificate x509Certificate; protected java.security.cert.Certificate[] certificateChain; protected KeyPair keyPair; protected JcaContentSignerBuilder jcaContentSignerBuilder; /** * Loads the keystore and obtains the private key, the public key and the associated certificate */ public SignatureHelper(File keyStoreFile, String keyStorePassword, String keyPassword) throws IOException { this(keyStoreFile, keyStorePassword, null, keyPassword); } /** * Loads the keystore and obtains the private key, the public key and the associated certificate referenced by the alias. * * @param keyStoreFile file holding the JKS keystore. * @param keyStorePassword password of the key store itself * @param keyAlias the alias referencing the private and public key pair. * @param keyPassword password protecting the private key */ public SignatureHelper(File keyStoreFile, String keyStorePassword, String keyAlias, String keyPassword) throws IOException { this(keyStoreFile, keyStorePassword, DEFAULT_KEY_STORE_TYPE, keyAlias, keyPassword); } /** * Loading keystore and fetching key * * @param keyStoreStream * Stream for keystore * @param keyStorePassword * Password to open keystore * @param keyAlias * Key alias, uses first key if set to null * @param keyPassword * Key password */ public SignatureHelper(InputStream keyStoreStream, String keyStorePassword, String keyAlias, String keyPassword) { this(keyStoreStream, keyStorePassword, DEFAULT_KEY_STORE_TYPE, keyAlias, keyPassword); } /** * Loads the keystore and obtains the private key, the public key and the associated certificate referenced by the alias. * * @param keyStoreFile * file holding the JKS keystore. * @param keyStorePassword * password of the key store itself * @param keyStoreType * key store type * @param keyAlias * the alias referencing the private and public key pair. * @param keyPassword * password protecting the private key */ public SignatureHelper(File keyStoreFile, String keyStorePassword, KeyStoreType keyStoreType, String keyAlias, String keyPassword) throws IOException { this(BCHelper.getProvider()); try (InputStream inputStream = Files.newInputStream(keyStoreFile.toPath())) { loadCertificate(loadKeyStore(inputStream, keyStorePassword, keyStoreType), keyAlias, keyPassword); } } /** * Loading keystore and fetching key * * @param keyStoreStream * Stream for keystore * @param keyStorePassword * Password to open keystore * @param keyStoreType * key store type * @param keyAlias * Key alias, uses first key if set to null * @param keyPassword * Key password */ public SignatureHelper(InputStream keyStoreStream, String keyStorePassword, KeyStoreType keyStoreType, String keyAlias, String keyPassword) { this(BCHelper.getProvider()); loadCertificate(loadKeyStore(keyStoreStream, keyStorePassword, keyStoreType), keyAlias, keyPassword); } /** * Obtains the private key, the public key and the associated certificate referenced by the alias from the given keystore * * @param keyStore * Loaded keystore * @param keyAlias * Key alias, uses first key if set to null * @param keyPassword * Key password */ public SignatureHelper(KeyStore keyStore, String keyAlias, String keyPassword) { this(BCHelper.getProvider()); loadCertificate(keyStore, keyAlias, keyPassword); } protected SignatureHelper(Provider provider) { this.provider = provider; jcaDigestCalculatorProviderBuilder = new JcaDigestCalculatorProviderBuilder(); if (provider != null) jcaDigestCalculatorProviderBuilder.setProvider(provider); } protected KeyStore loadKeyStore (InputStream keyStoreStream, String keyStorePassword, KeyStoreType keyStoreType) { try { KeyStore keyStore = KeyStore.getInstance(keyStoreType.name()); keyStore.load(keyStoreStream, keyStorePassword.toCharArray()); // TODO: find password of keystore return keyStore; } catch (Exception e) { throw new IllegalStateException(String.format("Load keystore; %s", e.getMessage()), e); } } protected void loadCertificate(KeyStore keyStore, String keyAlias, String keyPassword) { try { if (keyAlias == null) keyAlias = keyStore.aliases().nextElement(); x509Certificate = (X509Certificate) keyStore.getCertificate(keyAlias); certificateChain = keyStore.getCertificateChain(keyAlias); Key key = keyStore.getKey(keyAlias, keyPassword.toCharArray()); PrivateKey privateKey = (PrivateKey) key; keyPair = new KeyPair(x509Certificate.getPublicKey(), privateKey); jcaContentSignerBuilder = new JcaContentSignerBuilder(String.format("SHA1with%s", privateKey.getAlgorithm())); if (provider != null) jcaContentSignerBuilder.setProvider(provider); } catch (Exception e) { throw new IllegalStateException(String.format("Unable to retrieve private key from keystore: %s", e.getMessage()), e); } } /** * Sign content * * @param data Content to be signed * @return Signature */ byte[] signData(byte[] data) { try { DigestCalculatorProvider digestCalculatorProvider = jcaDigestCalculatorProviderBuilder.build(); ContentSigner contentSigner = jcaContentSignerBuilder.build(keyPair.getPrivate()); SignerInfoGenerator signerInfoGenerator = new JcaSignerInfoGeneratorBuilder(digestCalculatorProvider).build(contentSigner, x509Certificate); CMSSignedDataGenerator cmsSignedDataGenerator = new CMSSignedDataGenerator(); cmsSignedDataGenerator.addSignerInfoGenerator(signerInfoGenerator); cmsSignedDataGenerator.addCertificates(new JcaCertStore(Arrays.asList(certificateChain))); CMSSignedData cmsSignedData = cmsSignedDataGenerator.generate(new CMSProcessableByteArray(data), false); logger.debug(BaseEncoding.base64().encode(cmsSignedData.getEncoded())); return cmsSignedData.getEncoded(); } catch (Exception e) { throw new IllegalStateException(String.format("Unable to sign: %s", e.getMessage()), e); } } X509Certificate getX509Certificate() { return x509Certificate; } Certificate[] getCertificateChain() { return certificateChain; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy