/** * Return a new table with the passed in attribute added. * * @param attrType * @param attrValue * @return */ public AttributeTable add(ASN1ObjectIdentifier attrType, ASN1Encodable attrValue) { AttributeTable newTable = new AttributeTable(attributes); newTable.addAttribute(attrType, new Attribute(attrType, new DERSet(attrValue))); return newTable; }
private static ASN1Set buildSignedAttributes(byte[] hash, Date dateTime, X509Certificate cert) throws Exception { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new Attribute(CMSAttributes.contentType, new DERSet(PKCSObjectIdentifiers.data))); if (dateTime != null) v.add(new Attribute(CMSAttributes.signingTime, new DERSet(new Time(dateTime)))); v.add(new Attribute(CMSAttributes.messageDigest, new DERSet(new DEROctetString(hash)))); // CADES support section ASN1EncodableVector aaV2 = new ASN1EncodableVector(); AlgorithmIdentifier algoId = new AlgorithmIdentifier(new ASN1ObjectIdentifier(CMSSignedDataGenerator.DIGEST_SHA256), null); aaV2.add(algoId); byte[] dig = SignUtils.calculateHASH(CMSSignedDataGenerator.DIGEST_SHA256, cert.getEncoded()); aaV2.add(new DEROctetString(dig)); Attribute cades = new Attribute(PKCSObjectIdentifiers.id_aa_signingCertificateV2, new DERSet(new DERSequence(new DERSequence(new DERSequence(aaV2))))); v.add(cades); ASN1Set signedAttributes = new DERSet(v); return signedAttributes; }
/** * Added by Aiken Sam, 2006-11-15, modifed by Martin Brunecky 07/12/2007 * to start with the timeStampToken (signedData 1.2.840.113549.1.7.2). * Token is the TSA response without response status, which is usually * handled by the (vendor supplied) TSA request/response interface). * @param timeStampToken byte[] - time stamp token, DER encoded signedData * @return ASN1EncodableVector * @throws IOException */ private ASN1EncodableVector buildUnauthenticatedAttributes(byte[] timeStampToken) throws IOException { if (timeStampToken == null) return null; // @todo: move this together with the rest of the defintions String ID_TIME_STAMP_TOKEN = "1.2.840.113549.1.9.16.2.14"; // RFC 3161 id-aa-timeStampToken ASN1InputStream tempstream = new ASN1InputStream(new ByteArrayInputStream(timeStampToken)); ASN1EncodableVector unauthAttributes = new ASN1EncodableVector(); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new ASN1ObjectIdentifier(ID_TIME_STAMP_TOKEN)); // id-aa-timeStampToken ASN1Sequence seq = (ASN1Sequence) tempstream.readObject(); v.add(new DERSet(seq)); unauthAttributes.add(new DERSequence(v)); return unauthAttributes; }
@Override public Attribute getValue() throws SignerException { try { logger.info(cadesMessagesBundle.getString("info.tsa.connecting")); if (timeStampGenerator != null) { //Inicializa os valores para o timestmap timeStampGenerator.initialize(content, privateKey, certificates, hash); //Obtem o carimbo de tempo atraves do servidor TSA byte[] response = timeStampGenerator.generateTimeStamp(); //Valida o carimbo de tempo gerado timeStampGenerator.validateTimeStamp(content, response, hash); return new Attribute(new ASN1ObjectIdentifier(identifier), new DERSet(ASN1Primitive.fromByteArray(response))); } else { throw new SignerException(cadesMessagesBundle.getString("error.tsa.not.found")); } } catch (SecurityException | IOException ex) { } throw new UnsupportedOperationException(cadesMessagesBundle.getString("error.not.supported",getClass().getName())); }
@Override public Attribute getValue() { try { X509Certificate cert = (X509Certificate) certificates[0]; Digest digest = DigestFactory.getInstance().factoryDefault(); digest.setAlgorithm(DigestAlgorithmEnum.SHA_1); byte[] hash = digest.digest(cert.getEncoded()); X500Name dirName = new X500Name(cert.getSubjectDN().getName()); GeneralName name = new GeneralName(dirName); GeneralNames issuer = new GeneralNames(name); ASN1Integer serial = new ASN1Integer(cert.getSerialNumber()); IssuerSerial issuerSerial = new IssuerSerial(issuer, serial); ESSCertID essCertId = new ESSCertID(hash, issuerSerial); return new Attribute(new ASN1ObjectIdentifier(identifier), new DERSet(new DERSequence(new ASN1Encodable[]{new DERSequence(essCertId), new DERSequence(DERNull.INSTANCE)}))); } catch (CertificateEncodingException ex) { throw new SignerException(ex.getMessage()); } }
@Override public Attribute getValue() throws SignerException { try { logger.info(cadesMessagesBundle.getString("info.tsa.connecting")); if (timeStampGenerator != null) { //Inicializa os valores para o timestmap timeStampGenerator.initialize(content, privateKey, certificates, hash); //Obtem o carimbo de tempo atraves do servidor TSA byte[] response = timeStampGenerator.generateTimeStamp(); //Valida o carimbo de tempo gerado timeStampGenerator.validateTimeStamp(content, response, hash); return new Attribute(new ASN1ObjectIdentifier(identifier), new DERSet(ASN1Primitive.fromByteArray(response))); } else { throw new SignerException(cadesMessagesBundle.getString("error.tsa.not.found")); } } catch (SecurityException | IOException ex) { throw new SignerException(ex.getMessage()); } }
@Override public Attribute getValue() throws SignerException { try { X509Certificate cert = (X509Certificate) certificates[0]; X509Certificate issuerCert = (X509Certificate) certificates[1]; Digest digest = DigestFactory.getInstance().factoryDefault(); digest.setAlgorithm(DigestAlgorithmEnum.SHA_256); byte[] certHash = digest.digest(cert.getEncoded()); X500Name dirName = new X500Name(issuerCert.getSubjectX500Principal().getName()); GeneralName name = new GeneralName(dirName); GeneralNames issuer = new GeneralNames(name); ASN1Integer serialNumber = new ASN1Integer(cert.getSerialNumber()); IssuerSerial issuerSerial = new IssuerSerial(issuer, serialNumber); AlgorithmIdentifier algId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256);// SHA-256 ESSCertIDv2 essCertIDv2 = new ESSCertIDv2(algId, certHash, issuerSerial); // return new Attribute(new ASN1ObjectIdentifier(identifier), new DERSet(new DERSequence(essCertIDv2))); return new Attribute(new ASN1ObjectIdentifier(identifier), new DERSet(new DERSequence( new ASN1Encodable[] { new DERSequence(essCertIDv2) }))); } catch (CertificateEncodingException ex) { throw new SignerException(ex.getMessage()); } }
private static CMSSignedData addTimestamp(String tsaUrl, CMSSignedData signedData) throws IOException { Collection<SignerInformation> signerInfos = signedData.getSignerInfos().getSigners(); // get signature of first signer (should be the only one) SignerInformation si = signerInfos.iterator().next(); byte[] signature = si.getSignature(); // send request to TSA byte[] token = TimeStampingClient.getTimeStampToken(tsaUrl, signature, DigestType.SHA1); // create new SignerInformation with TS attribute Attribute tokenAttr = new Attribute(PKCSObjectIdentifiers.id_aa_signatureTimeStampToken, new DERSet(ASN1Primitive.fromByteArray(token))); ASN1EncodableVector timestampVector = new ASN1EncodableVector(); timestampVector.add(tokenAttr); AttributeTable at = new AttributeTable(timestampVector); si = SignerInformation.replaceUnsignedAttributes(si, at); signerInfos.clear(); signerInfos.add(si); SignerInformationStore newSignerStore = new SignerInformationStore(signerInfos); // create new signed data CMSSignedData newSignedData = CMSSignedData.replaceSigners(signedData, newSignerStore); return newSignedData; }
private void buildSignerInfo(DEREncodableVector body, byte[] signedHashContent, X509Certificate certContent, int hashId) throws Exception { // ----- Signers Info -------- final DEREncodableVector vec = new DEREncodableVector(); final DEREncodableVector signerinfoVector = new DEREncodableVector(); signerinfoVector.add(new DERInteger(SI_VERSION)); signerinfoVector.add(siAddCert(certContent)); signerinfoVector.add(siAddDigestAlgorithm(getHashAlg(hashId))); signerinfoVector .add(siAddDigestEncryptionAlgorithm(getHashSignAlg(hashId))); // Add the digest signerinfoVector.add(new DEROctetString(signedHashContent)); final DERSequence siSeq = new DERSequence(signerinfoVector); vec.add(siSeq); DERSet siSet = new DERSet(vec); body.add(siSet); }
private void buildSignerInfo(DEREncodableVector body, String signedHashContent, X509Certificate certContent, String hashId) throws CertificateEncodingException { // ----- Signers Info -------- final DEREncodableVector vec = new DEREncodableVector(); final DEREncodableVector signerinfoVector = new DEREncodableVector(); signerinfoVector.add(new DERInteger(SI_VERSION)); // 5 INT signerinfoVector.add(siAddCert(certContent)); signerinfoVector.add(siAddDigestAlgorithm(hashId)); signerinfoVector.add(siAddDigestEncryptionAlgorithm(ID_SHA1_RSA)); // 6 // OCT // STR // Add the digest signerinfoVector.add(new DEROctetString( getDerSignedDigest(signedHashContent))); final DERSequence siSeq = new DERSequence(signerinfoVector); // 4 SEQ vec.add(siSeq); DERSet siSet = new DERSet(vec); // 3 SET body.add(siSet); }
private void buildDigestAlg(final DEREncodableVector body, List<String> listHashId) { // ---------- algoritmos de digest final DEREncodableVector algos = new DEREncodableVector(); for (String next : listHashId) { algos.add(new DERObjectIdentifier(next)); // 4 OID algos.add(new DERNull()); // 4 NULL } final DEREncodableVector algoSet = new DEREncodableVector(); algoSet.add(new DERSequence(algos)); final DERSet digestAlgorithms = new DERSet(algoSet); // 2 // SET body.add(digestAlgorithms); }
private void buildSignerInfo(ASN1EncodableVector body, byte[] signedHashContent, X509Certificate certContent, int hashId) throws Exception { // ----- Signers Info -------- final ASN1EncodableVector vec = new ASN1EncodableVector(); final ASN1EncodableVector signerinfoVector = new ASN1EncodableVector(); signerinfoVector.add(new DERInteger(SI_VERSION)); signerinfoVector.add(siAddCert(certContent)); signerinfoVector.add(siAddDigestAlgorithm(getHashAlg(hashId))); signerinfoVector .add(siAddDigestEncryptionAlgorithm(getHashSignAlg(hashId))); // Add the digest signerinfoVector.add(new DEROctetString(signedHashContent)); final DERSequence siSeq = new DERSequence(signerinfoVector); vec.add(siSeq); DERSet siSet = new DERSet(vec); body.add(siSet); }
private void buildSignerInfo(ASN1EncodableVector body, String signedHashContent, X509Certificate certContent, String hashId) throws CertificateEncodingException { // ----- Signers Info -------- final ASN1EncodableVector vec = new ASN1EncodableVector(); final ASN1EncodableVector signerinfoVector = new ASN1EncodableVector(); signerinfoVector.add(new DERInteger(SI_VERSION)); // 5 INT signerinfoVector.add(siAddCert(certContent)); signerinfoVector.add(siAddDigestAlgorithm(hashId)); signerinfoVector.add(siAddDigestEncryptionAlgorithm(ID_SHA1_RSA)); // 6 // OCT // STR // Add the digest signerinfoVector.add(new DEROctetString( getDerSignedDigest(signedHashContent))); final DERSequence siSeq = new DERSequence(signerinfoVector); // 4 SEQ vec.add(siSeq); DERSet siSet = new DERSet(vec); // 3 SET body.add(siSet); }
private void buildDigestAlg(final ASN1EncodableVector body, List<String> listHashId) { // ---------- algoritmos de digest final ASN1EncodableVector algos = new ASN1EncodableVector(); for (String next : listHashId) { algos.add(new DERObjectIdentifier(next)); // 4 OID algos.add(new DERNull()); // 4 NULL } final ASN1EncodableVector algoSet = new ASN1EncodableVector(); algoSet.add(new DERSequence(algos)); final DERSet digestAlgorithms = new DERSet(algoSet); // 2 // SET body.add(digestAlgorithms); }
/** * We are extending CMS Signature * * @param signer * information about signer * @return information about SignerInformation */ private SignerInformation signTimeStamp(SignerInformation signer) throws IOException, TSPException { AttributeTable unsignedAttributes = signer.getUnsignedAttributes(); ASN1EncodableVector vector = new ASN1EncodableVector(); if (unsignedAttributes != null) { vector = unsignedAttributes.toASN1EncodableVector(); } byte[] token = tsaClient.getTimeStampToken(signer.getSignature()); ASN1ObjectIdentifier oid = PKCSObjectIdentifiers.id_aa_signatureTimeStampToken; ASN1Encodable signatureTimeStamp = new Attribute(oid, new DERSet(ASN1Primitive.fromByteArray(token))); vector.add(signatureTimeStamp); Attributes signedAttributes = new Attributes(vector); SignerInformation newSigner = SignerInformation.replaceUnsignedAttributes(signer, new AttributeTable(signedAttributes)); return newSigner; }
private void addSigningTimeAttribute(final CAdESSignatureParameters parameters, final ASN1EncodableVector signedAttributes) { if (!padesUsage) { /* * In PAdES, we don't include the signing time : ETSI TS 102 778-3 V1.2.1 (2010-07): 4.5.3 signing-time * Attribute */ final Date signingDate = parameters.bLevel().getSigningDate(); if (signingDate != null) { final DERSet attrValues = new DERSet(new Time(signingDate)); final Attribute attribute = new Attribute(pkcs_9_at_signingTime, attrValues); signedAttributes.add(attribute); } } }
/** * ETSI TS 101 733 V2.2.1 (2013-04) * * 5.11.1 commitment-type-indication Attribute * There may be situations where a signer wants to explicitly indicate to a verifier that by signing the data, it * illustrates a * type of commitment on behalf of the signer. The commitment-type-indication attribute conveys such * information. * * @param parameters * @param signedAttributes */ private void addCommitmentType(final CAdESSignatureParameters parameters, final ASN1EncodableVector signedAttributes) { // TODO (19/08/2014): commitmentTypeQualifier is not implemented final BLevelParameters bLevelParameters = parameters.bLevel(); final List<String> commitmentTypeIndications = bLevelParameters.getCommitmentTypeIndications(); if (Utils.isCollectionNotEmpty(commitmentTypeIndications)) { final int size = commitmentTypeIndications.size(); ASN1Encodable[] asn1Encodables = new ASN1Encodable[size]; for (int ii = 0; ii < size; ii++) { final String commitmentTypeId = commitmentTypeIndications.get(ii); final ASN1ObjectIdentifier objectIdentifier = new ASN1ObjectIdentifier(commitmentTypeId); // final CommitmentTypeIndication commitmentTypeIndication = new // CommitmentTypeIndication(objectIdentifier); // final ASN1Primitive asn1Primitive = commitmentTypeIndication.toASN1Primitive(); asn1Encodables[ii] = new DERSequence(objectIdentifier); } final DERSet attrValues = new DERSet(asn1Encodables); final Attribute attribute = new Attribute(id_aa_ets_commitmentType, attrValues); signedAttributes.add(attribute); } }
public ASN1Primitive toASN1Primitive() { ASN1EncodableVector seq = new ASN1EncodableVector(); seq.add(version); ASN1EncodableVector certSet = new ASN1EncodableVector(); for (int i = 0; i < certList.length; i++) { certSet.add(certList[i]); } seq.add(new DERSet(certSet)); return new DERSequence(seq); }
public SMIMEEncryptionKeyPreferenceAttribute( RecipientKeyIdentifier rKeyId) { super(SMIMEAttributes.encrypKeyPref, new DERSet(new DERTaggedObject(false, 1, rKeyId))); }
/** * @param sKeyId the subjectKeyIdentifier value (normally the X.509 one) */ public SMIMEEncryptionKeyPreferenceAttribute( ASN1OctetString sKeyId) { super(SMIMEAttributes.encrypKeyPref, new DERSet(new DERTaggedObject(false, 2, sKeyId))); }
/** * Create a single valued RDN. * * @param oid RDN type. * @param value RDN value. */ public RDN(ASN1ObjectIdentifier oid, ASN1Encodable value) { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(oid); v.add(value); this.values = new DERSet(new DERSequence(v)); }
static ASN1Set createDerSetFromList(List derObjects) { ASN1EncodableVector v = new ASN1EncodableVector(); for (Iterator it = derObjects.iterator(); it.hasNext();) { v.add((ASN1Encodable)it.next()); } return new DERSet(v); }
private ASN1Set getAttributeSet( AttributeTable attr) { if (attr != null) { return new DERSet(attr.toASN1EncodableVector()); } return null; }
protected ASN1Set getAttributeSet( AttributeTable attr) { if (attr != null) { return new DERSet(attr.toASN1EncodableVector()); } return null; }
private ASN1Primitive createDERForRecipient(byte[] in, X509Certificate cert) throws IOException, GeneralSecurityException { String s = "1.2.840.113549.3.2"; AlgorithmParameterGenerator algorithmparametergenerator = AlgorithmParameterGenerator.getInstance(s); AlgorithmParameters algorithmparameters = algorithmparametergenerator.generateParameters(); ByteArrayInputStream bytearrayinputstream = new ByteArrayInputStream(algorithmparameters.getEncoded("ASN.1")); ASN1InputStream asn1inputstream = new ASN1InputStream(bytearrayinputstream); ASN1Primitive derobject = asn1inputstream.readObject(); KeyGenerator keygenerator = KeyGenerator.getInstance(s); keygenerator.init(128); SecretKey secretkey = keygenerator.generateKey(); Cipher cipher = Cipher.getInstance(s); cipher.init(1, secretkey, algorithmparameters); byte[] abyte1 = cipher.doFinal(in); DEROctetString deroctetstring = new DEROctetString(abyte1); KeyTransRecipientInfo keytransrecipientinfo = computeRecipientInfo(cert, secretkey.getEncoded()); DERSet derset = new DERSet(new RecipientInfo(keytransrecipientinfo)); AlgorithmIdentifier algorithmidentifier = new AlgorithmIdentifier(new ASN1ObjectIdentifier(s), derobject); EncryptedContentInfo encryptedcontentinfo = new EncryptedContentInfo(PKCSObjectIdentifiers.data, algorithmidentifier, deroctetstring); EnvelopedData env = new EnvelopedData(null, derset, encryptedcontentinfo, (org.bouncycastle.asn1.ASN1Set) null); ContentInfo contentinfo = new ContentInfo(PKCSObjectIdentifiers.envelopedData, env); return contentinfo.toASN1Primitive(); }
/** * Return a new table with the passed in attribute added. * * @param attrType the type of the attribute to add. * @param attrValue the value corresponding to the attribute (will be wrapped in a SET). * @return a new table with the extra attribute in it. */ public AttributeTable add(ASN1ObjectIdentifier attrType, ASN1Encodable attrValue) { AttributeTable newTable = new AttributeTable(attributes); newTable.addAttribute(attrType, new Attribute(attrType, new DERSet(attrValue))); return newTable; }
/** * Return a signer information object with passed in SignerInformationStore representing counter * signatures attached as an unsigned attribute. * * @param signerInformation the signerInfo to be used as the basis. * @param counterSigners signer info objects carrying counter signature. * @return a copy of the original SignerInformationObject with the changed attributes. */ public static SignerInformation addCounterSigners( SignerInformation signerInformation, SignerInformationStore counterSigners) { // TODO Perform checks from RFC 3852 11.4 SignerInfo sInfo = signerInformation.info; AttributeTable unsignedAttr = signerInformation.getUnsignedAttributes(); ASN1EncodableVector v; if (unsignedAttr != null) { v = unsignedAttr.toASN1EncodableVector(); } else { v = new ASN1EncodableVector(); } ASN1EncodableVector sigs = new ASN1EncodableVector(); for (Iterator it = counterSigners.getSigners().iterator(); it.hasNext();) { sigs.add(((SignerInformation)it.next()).toASN1Structure()); } v.add(new Attribute(CMSAttributes.counterSignature, new DERSet(sigs))); return new SignerInformation( new SignerInfo(sInfo.getSID(), sInfo.getDigestAlgorithm(), sInfo.getAuthenticatedAttributes(), sInfo.getDigestEncryptionAlgorithm(), sInfo.getEncryptedDigest(), new DERSet(v)), signerInformation.contentType, signerInformation.content, null); }
@Override public Attribute getValue() throws SignerException { try { int chainSize = certificates.length -1; OtherCertID[] arrayOtherCertID = new OtherCertID[chainSize]; for (int i = 1; i <= chainSize; i++ ){ X509Certificate issuerCert = null; X509Certificate cert = (X509Certificate) certificates[i]; if (i < chainSize){ issuerCert = (X509Certificate) certificates[i+1]; }else{ // raiz issuerCert = (X509Certificate) certificates[i]; } Digest digest = DigestFactory.getInstance().factoryDefault(); digest.setAlgorithm(DigestAlgorithmEnum.SHA_256); byte[] certHash = digest.digest(cert.getEncoded()); X500Name dirName = new X500Name(issuerCert.getSubjectX500Principal().getName()); GeneralName name = new GeneralName(dirName); GeneralNames issuer = new GeneralNames(name); ASN1Integer serialNumber = new ASN1Integer(cert.getSerialNumber()); IssuerSerial issuerSerial = new IssuerSerial(issuer, serialNumber); AlgorithmIdentifier algId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256); OtherCertID otherCertID = new OtherCertID(algId, certHash, issuerSerial); arrayOtherCertID[i -1] = otherCertID; } return new Attribute(new ASN1ObjectIdentifier(identifier), new DERSet(new ASN1Encodable[] { new DERSequence(arrayOtherCertID) })); } catch (CertificateEncodingException e) { throw new SignerException(e.getMessage()); } }
/** * org.bouncycastle.asn1.ASN1ObjectIdentifier sigPolicyId * org.bouncycastle.asn1.esf.OtherHashAlgAndValue sigPolicyHash * List<org.bouncycastle.asn1.esf.SigPolicyQualifierInfo> sigPolicyQualifierInfos */ @Override public Attribute getValue() { //Atributo 1 ASN1ObjectIdentifier sigPolicyId = new ASN1ObjectIdentifier(signaturePolicy.getSignPolicyInfo().getSignPolicyIdentifier().getValue()); //Atributo 2 OtherHashAlgAndValue sigPolicyHash = new OtherHashAlgAndValue(new AlgorithmIdentifier( new ASN1ObjectIdentifier(signaturePolicy.getSignPolicyHashAlg().getAlgorithm().getValue())), signaturePolicy.getSignPolicyHash().getDerOctetString()); //Atributo 3 List<SigPolicyQualifierInfo> sigPolicyQualifierInfos = new ArrayList<SigPolicyQualifierInfo>(); ASN1ObjectIdentifier sigPolicyQualifierId = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.5.1"); DERIA5String sigQualifier = new DERIA5String(signaturePolicy.getSignPolicyURI()); SigPolicyQualifierInfo bcSigPolicyQualifierInfo = new SigPolicyQualifierInfo(sigPolicyQualifierId, sigQualifier); sigPolicyQualifierInfos.add(bcSigPolicyQualifierInfo); SigPolicyQualifiers sigPolicyQualifiers = new SigPolicyQualifiers(sigPolicyQualifierInfos.toArray(new SigPolicyQualifierInfo[]{})); SignaturePolicyId signaturePolicyId = new SignaturePolicyId(sigPolicyId, sigPolicyHash, sigPolicyQualifiers); return new Attribute(new ASN1ObjectIdentifier(oid), new DERSet(signaturePolicyId)); }
@Override public Attribute getValue() { try { if (this.hash == null){ java.security.MessageDigest md = java.security.MessageDigest.getInstance(signaturePolicy.getSignPolicyHashAlg().getAlgorithm().getValue()); this.hash = md.digest(content); } return new Attribute(new ASN1ObjectIdentifier(identifier), new DERSet(new DEROctetString(this.hash))); } catch (NoSuchAlgorithmException ex) { logger.info(ex.getMessage()); return null; } }
/** * <a href="http://stackoverflow.com/questions/41767351/create-pkcs7-signature-from-file-digest"> * Create pkcs7 signature from file digest * </a> * <p> * The OP's <code>sign</code> method after fixing some errors. The * OP's original method is {@link #signBySnox(InputStream)}. The * errors were * </p> * <ul> * <li>multiple attempts at reading the {@link InputStream} parameter; * <li>convoluted creation of final CMS container. * </ul> * <p> * Additionally this method uses SHA256 instead of SHA-1. * </p> */ public byte[] signWithSeparatedHashing(InputStream content) throws IOException { try { // Digest generation step MessageDigest md = MessageDigest.getInstance("SHA256", "BC"); byte[] digest = md.digest(IOUtils.toByteArray(content)); // Separate signature container creation step List<Certificate> certList = Arrays.asList(chain); JcaCertStore certs = new JcaCertStore(certList); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); Attribute attr = new Attribute(CMSAttributes.messageDigest, new DERSet(new DEROctetString(digest))); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(attr); SignerInfoGeneratorBuilder builder = new SignerInfoGeneratorBuilder(new BcDigestCalculatorProvider()) .setSignedAttributeGenerator(new DefaultSignedAttributeTableGenerator(new AttributeTable(v))); AlgorithmIdentifier sha256withRSA = new DefaultSignatureAlgorithmIdentifierFinder().find("SHA256withRSA"); CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); InputStream in = new ByteArrayInputStream(chain[0].getEncoded()); X509Certificate cert = (X509Certificate) certFactory.generateCertificate(in); gen.addSignerInfoGenerator(builder.build( new BcRSAContentSignerBuilder(sha256withRSA, new DefaultDigestAlgorithmIdentifierFinder().find(sha256withRSA)) .build(PrivateKeyFactory.createKey(pk.getEncoded())), new JcaX509CertificateHolder(cert))); gen.addCertificates(certs); CMSSignedData s = gen.generate(new CMSAbsentContent(), false); return s.getEncoded(); } catch (Exception e) { e.printStackTrace(); throw new IOException(e); } }