Date: Fri, 29 Mar 2024 08:00:00 +0300 (MSK) Message-ID: <567515570.12221.1711688400574@dev.rutoken.ru> Subject: Exported From Confluence MIME-Version: 1.0 Content-Type: multipart/related; boundary="----=_Part_12220_144293343.1711688400573" ------=_Part_12220_144293343.1711688400573 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Content-Location: file:///C:/exported.html
Bouncy Castle =E2=80=93 =D0=B1=D0=B8=D0=B1=D0=BB=D0=B8=D0= =BE=D1=82=D0=B5=D0=BA=D0=B0 =D1=81 =D0=BE=D1=82=D0=BA=D1=80=D1=8B=D1=82=D1= =8B=D0=BC =D0=B8=D1=81=D1=85=D0=BE=D0=B4=D0=BD=D1=8B=D0=BC =D0=BA=D0=BE=D0= =B4=D0=BE=D0=BC =D0=BF=D1=80=D0=B5=D0=B4=D0=BE=D1=81=D1=82=D0=B0=D0=B2=D0= =BB=D1=8F=D1=8E=D1=89=D0=B0=D1=8F API =D0=BD=D0=B0=D0=B4 =D0=BA=D1=80=D0=B8= =D0=BF=D1=82=D0=BE=D0=B3=D1=80=D0=B0=D1=84=D0=B8=D1=87=D0=B5=D1=81=D0=BA=D0= =B8=D0=BC=D0=B8 =D0=BE=D0=BF=D0=B5=D1=80=D0=B0=D1=86=D0=B8=D1=8F=D0=BC=D0= =B8. =D0=A1=D0=B5=D0=B9=D1=87=D0=B0=D1=81 =D1=8D=D1=82=D0=B0 =D0=B1=D0=B8= =D0=B1=D0=BB=D0=B8=D0=BE=D1=82=D0=B5=D0=BA=D0=B0 =D1=81=D1=83=D1=89=D0=B5= =D1=81=D1=82=D0=B2=D1=83=D0=B5=D1=82 =D0=B4=D0=BB=D1=8F =D0=B4=D0=B2=D1=83= =D1=85 =D1=8F=D0=B7=D1=8B=D0=BA=D0=BE=D0=B2 =E2=80=93 Java =D0=B8 =D0= =A1# =D0=B8 =D0=BF=D0=BE =D1=81=D1=83=D1=82=D0=B8 =D1=8F=D0=B2=D0=BB=D1=8F= =D0=B5=D1=82=D1=81=D1=8F =D0=B0=D0=BD=D0=B0=D0=BB=D0=BE=D0=B3=D0=BE=D0=BC O= penSSL =D0=B2 =D0=BD=D0=B8=D1=85.
=D0=91=D0=B8=D0=B1=D0=BB=D0=B8=D0=BE=D1=82=D0=B5=D0=BA=D0=B0 Bouncy Cast= le =D1=82=D0=B0=D0=BA=D0=B6=D0=B5 =D0=BF=D1=80=D0=B5=D0=B4=D0=BE=D1=81=D1= =82=D0=B0=D0=B2=D0=BB=D1=8F=D0=B5=D1=82 =D0=B2=D0=BE=D0=B7=D0=BC=D0=BE=D0= =B6=D0=BD=D0=BE=D1=81=D1=82=D1=8C =D0=BF=D0=BE =D1=80=D0=B0=D0=B1=D0=BE=D1= =82=D0=B5 =D1=81 =D1=82=D0=BE=D0=BA=D0=B5=D0=BD=D0=B0=D0=BC=D0=B8. =D0=AD= =D1=82=D0=BE =D0=B2=D0=BE=D0=B7=D0=BC=D0=BE=D0=B6=D0=BD=D0=BE =D0=B7=D0=B0 = =D1=81=D1=87=D0=B5=D1=82 =D1=80=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0=D1=86= =D0=B8=D0=B8 =D0=BA=D0=BB=D0=B0=D1=81=D1=81=D0=BE=D0=B2, =D1=80=D0=B5=D0=B0= =D0=BB=D0=B8=D0=B7=D1=83=D1=8E=D1=89=D0=B8=D1=85 =D0=BF=D1=80=D0=B8=D0=BC= =D0=B8=D1=82=D0=B8=D0=B2=D0=BD=D1=8B=D0=B5 =D0=BA=D1=80=D0=B8=D0=BF=D1=82= =D0=BE=D0=B3=D1=80=D0=B0=D1=84=D0=B8=D1=87=D0=B5=D1=81=D0=BA=D0=B8=D0=B5 = =D0=BE=D0=BF=D0=B5=D1=80=D0=B0=D1=86=D0=B8=D0=B8 (=D1=88=D0=B8=D1=84=D1=80= =D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5, =D0=B2=D0=B7=D1=8F=D1=82=D0=B8=D0=B5 = =D1=81=D1=8B=D1=80=D0=BE=D0=B9 =D0=BF=D0=BE=D0=B4=D0=BF=D0=B8=D1=81=D0=B8, = =D1=85=D0=B5=D1=88=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5 =D0=B8 = =D1=82.=D0=B4.), =D0=B8 =D0=BF=D0=B5=D1=80=D0=B5=D0=B4=D0=B0=D1=87=D0=B5 = =D0=B8=D1=85 =D0=B1=D0=B8=D0=B1=D0=BB=D0=B8=D0=BE=D1=82=D0=B5=D0=BA=D0=B5 B= ouncy Castle. =D0=9F=D1=80=D0=B8=D0=BC=D0=B5=D1=80 =D1=80=D0=B5=D0=B0=D0=BB= =D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D0=B8 =D1=82=D0=B0=D0=BA=D0=B8=D1=85 =D0=BF= =D1=80=D0=B8=D0=BC=D0=B8=D1=82=D0=B8=D0=B2=D0=BD=D1=8B=D1=85 =D0=BA=D0=BB= =D0=B0=D1=81=D1=81=D0=BE=D0=B2, =D0=BC=D0=BE=D0=B6=D0=BD=D0=BE =D0=BD=D0=B0= =D0=B9=D1=82=D0=B8 =D0=B2 Rutoken SDK =D0=B2 =D0=B4= =D0=B8=D1=80=D0=B5=D0=BA=D1=82=D0=BE=D1=80=D0=B8=D0=B8 /sdk/java/sample= s/pkcs11/src/ru/rutoken/samples/pkcs11/bouncycastle/bcprimitives/.
=D0=9D=D0=B0=D0=BF=D1=80=D0=B8=D0=BC=D0=B5=D1=80, =D0=B4=D0=BB=D1=8F =D1= =80=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D0=B8 =D0=BF=D1=80=D0= =B8=D0=BC=D0=B8=D1=82=D0=B8=D0=B2=D0=B0 =D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0= =B5=D0=BD=D0=B8=D1=8F =D1=85=D0=B5=D1=88=D0=B0 =D0=BD=D1=83=D0=B6=D0=BD=D0= =BE =D1=80=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D1=8C =D1= =84=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D0=B8 =D0=B0=D0=B1=D1=81=D1=82=D1=80=D0= =B0=D0=BA=D1=82=D0=BD=D0=BE=D0=B3=D0=BE =D0=BA=D0=BB=D0=B0=D1=81=D1=81=D0= =B0 DigestCalculator. =D0=AD=D1=82=D0=BE =D0=BC=D0=BE=D0=B6=D0=B5=D1=82 =D0= =B2=D1=8B=D0=B3=D0=BB=D1=8F=D0=B4=D0=B5=D1=82=D1=8C =D1=82=D0=B0=D0=BA:
package= ru.rutoken.samples.pkcs11.bouncycastle.bcprimitives; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.operator.DigestCalculator; import ru.rutoken.samples.pkcs11.Pkcs11Exception; import ru.rutoken.samples.pkcs11.bouncycastle.pkcs11operations.Pkcs11GostDi= gester; import java.io.ByteArrayOutputStream; import java.io.OutputStream; import java.util.Objects; class GostDigestCalculator implements DigestCalculator { private final Pkcs11GostDigester mPkcs11GostDigester; private final ByteArrayOutputStream mStream =3D new ByteArrayOutputStre= am(); GostDigestCalculator(Pkcs11GostDigester pkcs11GostDigester) { mPkcs11GostDigester =3D Objects.requireNonNull(pkcs11GostDigester); } @Override public AlgorithmIdentifier getAlgorithmIdentifier() { return mPkcs11GostDigester.getDigestAlgorithm().getAlgorithmIdentif= ier(); } @Override public byte[] getDigest() { byte[] data =3D mStream.toByteArray(); try { byte[] digestedData =3D mPkcs11GostDigester.digest(data); mStream.reset(); return digestedData; } catch (Pkcs11Exception e) { throw new RuntimeException(e); } } @Override public OutputStream getOutputStream() { return mStream; } }
=D0=AD=D1=82=D0=BE=D1=82 =D0=BA=D0=BB=D0=B0=D1=81=D1=81 =D0=B8=D1=81=D0= =BF=D0=BE=D0=BB=D1=8C=D0=B7=D1=83=D0=B5=D1=82 =D1=83=D0=B4=D0=BE=D0=B1=D0= =BD=D1=8B=D0=B9 =D0=BA=D0=BB=D0=B0=D1=81=D1=81-=D0=BE=D0=B1=D0=B5=D1=80=D1= =82=D0=BA=D1=83 Pkcs11GostDigester =D0=BD=D0=B0=D0=B4 PKCS#11 =D1=84=D1=83= =D0=BD=D0=BA=D1=86=D0=B8=D1=8F=D0=BC=D0=B8 =D0=B4=D0=BB=D1=8F =D0=BF=D0=BE= =D0=BB=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D1=8F =D1=85=D0=B5=D1=88=D0=B0. =D0=94= =D0=B5=D1=82=D0=B0=D0=BB=D0=B8 =D1=80=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0= =D1=86=D0=B8=D0=B8 =D0=BC=D0=BE=D0=B6=D0=BD=D0=BE =D0=BF=D0=BE=D1=81=D0=BC= =D0=BE=D1=82=D1=80=D0=B5=D1=82=D1=8C =D0=B2 =D0=BF=D1=80=D0=B8=D0=BC=D0=B5= =D1=80=D0=B0=D1=85 sdk:
package= ru.rutoken.samples.pkcs11.bouncycastle.pkcs11operations; import com.sun.jna.Memory; import com.sun.jna.NativeLong; import com.sun.jna.Pointer; import com.sun.jna.ptr.NativeLongByReference; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.rosstandart.RosstandartObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import ru.rutoken.pkcs11jna.CK_MECHANISM; import ru.rutoken.pkcs11jna.Pkcs11; import ru.rutoken.pkcs11jna.RtPkcs11Constants; import ru.rutoken.samples.Constants; import ru.rutoken.samples.pkcs11.Pkcs11Exception; import ru.rutoken.samples.pkcs11.RtPkcs11Library; public class Pkcs11GostDigester { private final DigestAlgorithm mDigestAlgorithm; private final long mSessionHandle; public Pkcs11GostDigester(DigestAlgorithm digestAlgorithm, long session= Handle) { mDigestAlgorithm =3D digestAlgorithm; mSessionHandle =3D sessionHandle; } public DigestAlgorithm getDigestAlgorithm() { return mDigestAlgorithm; } public byte[] digest(byte[] data) throws Pkcs11Exception { final Pkcs11 pkcs11 =3D RtPkcs11Library.getPkcs11Interface(); Pointer parameter =3D new Memory(mDigestAlgorithm.getAlgorithmParam= set().length); parameter.write(0, mDigestAlgorithm.getAlgorithmParamset(), 0, mDig= estAlgorithm.getAlgorithmParamset().length); // Pass null as parameter and 0 as parameter length if you want to = perform hardware digest final CK_MECHANISM mechanism =3D new CK_MECHANISM(new NativeLong(mD= igestAlgorithm.getPkcsMechanism()), parameter, new NativeLong(mDigestAlgori= thm.getAlgorithmParamset().length)); NativeLong rv =3D pkcs11.C_DigestInit(new NativeLong(mSessionHandle= ), mechanism); Pkcs11Exception.throwIfNotOk("C_DigestInit failed", rv); final NativeLongByReference count =3D new NativeLongByReference(); rv =3D pkcs11.C_Digest(new NativeLong(mSessionHandle), data, new Na= tiveLong(data.length), null, count); Pkcs11Exception.throwIfNotOk("C_Digest failed", rv); final byte[] digest =3D new byte[count.getValue().intValue()]; rv =3D pkcs11.C_Digest(new NativeLong(mSessionHandle), data, new Na= tiveLong(data.length), digest, count); Pkcs11Exception.throwIfNotOk("C_Digest failed", rv); return digest; } public enum DigestAlgorithm { GOSTR3411_1994(RtPkcs11Constants.CKM_GOSTR3411, new AlgorithmIdenti= fier(CryptoProObjectIdentifiers.gostR3411), Constants.ATTR_GOSTR3411_1994), GOSTR3411_2012_256(RtPkcs11Constants.CKM_GOSTR3411_12_256, new Algo= rithmIdentifier(RosstandartObjectIdentifiers.id_tc26_gost_3411_12_256), Con= stants.ATTR_GOSTR3411_2012_256), GOSTR3411_2012_512(RtPkcs11Constants.CKM_GOSTR3411_12_512, new Algo= rithmIdentifier(RosstandartObjectIdentifiers.id_tc26_gost_3411_12_512), Con= stants.ATTR_GOSTR3411_2012_512); private final long mPkcsMechanism; private final AlgorithmIdentifier mAlgorithmIdentifier; private final byte[] mParamset; DigestAlgorithm(long pkcsMechanism, AlgorithmIdentifier algorithmId= entifier, byte[] paramset) { mPkcsMechanism =3D pkcsMechanism; mAlgorithmIdentifier =3D algorithmIdentifier; mParamset =3D paramset; } public long getPkcsMechanism() { return mPkcsMechanism; } public AlgorithmIdentifier getAlgorithmIdentifier() { return mAlgorithmIdentifier; } public byte[] getAlgorithmParamset() { return mParamset; } } }
=D0=9F=D0=BE=D0=BB=D1=83=D1=87=D0=B5=D0=BD=D0=BD=D1=8B=D0=B9 =D0=BF=D1= =80=D0=B8=D0=BC=D0=B8=D1=82=D0=B8=D0=B2 =D0=BC=D0=BE=D0=B6=D0=BD=D0=BE =D0= =B8=D1=81=D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D1=8C =D0= =B2=D0=B5=D0=B7=D0=B4=D0=B5, =D0=B3=D0=B4=D0=B5 =D1=82=D1=80=D0=B5=D0=B1=D1= =83=D0=B5=D1=82=D1=81=D1=8F =D0=BE=D0=B1=D1=8A=D0=B5=D0=BA=D1=82 =D1=81 =D0= =B8=D0=BD=D1=82=D0=B5=D1=80=D1=84=D0=B5=D0=B9=D1=81=D0=BE=D0=BC Digest= Calculator. =D0=92 =D1=81=D0=B2=D0=BE=D0=B5=D0=BC =D0=BF=D1=80=D0=B8=D0=BB= =D0=BE=D0=B6=D0=B5=D0=BD=D0=B8=D0=B8 =D0=B2=D1=8B =D0=BC=D0=BE=D0=B6=D0=B5= =D1=82=D0=B5 =D0=B8=D1=81=D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0= =D1=82=D1=8C =D0=B3=D0=BE=D1=82=D0=BE=D0=B2=D1=8B=D0=B5 =D1=80=D0=B5=D0=B0= =D0=BB=D0=B8=D0=B7=D0=BE=D0=B2=D0=B0=D0=BD=D0=BD=D1=8B=D0=B5 =D0=BF=D1=80= =D0=B8=D0=BC=D0=B8=D1=82=D0=B8=D0=B2=D1=8B =D0=B8=D0=B7 =D0=BD=D0=B0=D1=88= =D0=B5=D0=B3=D0=BE SDK =D0=B8 =D0=B4=D0=BE=D0=BF=D0=BE=D0=BB=D0=BD=D1=8F=D1= =82=D1=8C =D0=B8=D1=85.
=D0=9F=D1=80=D0=B8=D0=BC=D0=B5=D1=80 =D0=B8=D1=81=D0=BF=D0=BE=D0=BB=D1= =8C=D0=B7=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F =D0=BF=D1=80=D0=B8=D0=BC=D0= =B8=D1=82=D0=B8=D0=B2=D0=B0 =D0=B4=D0=BB=D1=8F =D1=80=D0=B5=D0=B0=D0=BB=D0= =B8=D0=B7=D0=B0=D1=86=D0=B8=D0=B8 =D0=BC=D0=BD=D0=BE=D0=B6=D0=B5=D1=81=D1= =82=D0=B2=D0=B5=D0=BD=D0=BD=D0=BE=D0=B9 =D0=BF=D0=BE=D0=B4=D0=BF=D0=B8=D1= =81=D0=B8:
package= ru.rutoken.samples.pkcs11.bouncycastle; import com.sun.jna.NativeLong; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cmp.PKIStatus; import org.bouncycastle.asn1.cms.Attribute; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.rosstandart.RosstandartObjectIdentifiers; import org.bouncycastle.asn1.tsp.TimeStampResp; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cms.*; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.tsp.TSPException; import org.bouncycastle.tsp.TimeStampRequest; import org.bouncycastle.tsp.TimeStampRequestGenerator; import org.bouncycastle.tsp.TimeStampResponse; import ru.rutoken.pkcs11jna.CK_ATTRIBUTE; import ru.rutoken.pkcs11jna.Pkcs11; import ru.rutoken.pkcs11jna.Pkcs11Constants; import ru.rutoken.samples.Constants; import ru.rutoken.samples.pkcs11.RtPkcs11Library; import ru.rutoken.samples.pkcs11.Util; import ru.rutoken.samples.pkcs11.bouncycastle.CmsSignVerifyAttachedGOSTR341= 0_2012_256; import ru.rutoken.samples.pkcs11.bouncycastle.cmsoperations.GostCmsOperatio= ns; import ru.rutoken.samples.pkcs11.bouncycastle.bcprimitives.GostContentSigne= r; import ru.rutoken.samples.pkcs11.bouncycastle.pkcs11operations.Pkcs11GostSi= gner; import ru.rutoken.samples.pkcs11.bouncycastle.pkcs11operations.Pkcs11Operat= ions; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.Security; import java.util.*; public class CmsAddSigner { public static void main(String[] args) { try { Security.addProvider(new BouncyCastleProvider()); =09=09=09 =09=09=09// =D0=B7=D0=B0=D0=B3=D1=80=D1=83=D0=B6=D0=B0=D0=B5=D0=BC =D0=B8= =D0=BC=D0=B5=D1=8E=D1=89=D0=B8=D0=B9=D1=81=D1=8F =D1=84=D0=B0=D0=B9=D0=BB = =D1=81 CMS CMSSignedData cms =3D Util.readCmsFromFile("pkcs11/cms.pem"); Util.printString("Original CMS signature in PEM is:", Util.cmsT= oPem(cms.getEncoded())); =09=09=09// =D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D1=8F=D0=B5=D0=BC =D0=BF= =D0=BE=D0=B4=D0=BF=D0=B8=D1=81=D1=8C =D0=B2 =D1=81=D1=83=D1=89=D0=B5=D1=81= =D1=82=D0=B2=D1=83=D1=8E=D1=89=D1=83=D1=8E CMS -- =D0=BF=D0=BE=D0=BB=D1=83= =D1=87=D0=B0=D0=B5=D0=BC =D0=BD=D0=BE=D0=B2=D1=8B=D0=B9 CMS cms =3D addSignerToCms(cms); Util.printString("CMS with added signature in PEM is:", Util.cm= sToPem(cms.getEncoded())); System.out.println("Sample has been completed successfully."); } catch (Exception e) { System.out.println("Sample has failed:"); e.printStackTrace(); } } =09// =D1=88=D0=B0=D0=B1=D0=BB=D0=BE=D0=BD =D1=81=D0=B5=D1=80=D1=82=D0=B8= =D1=84=D0=B8=D0=BA=D0=B0=D1=82=D0=B0 =D0=BD=D0=B0 =D1=82=D0=BE=D0=BA=D0=B5= =D0=BD=D0=B5 =D0=BD=D0=BE=D0=B2=D0=BE=D0=B3=D0=BE =D0=BF=D0=BE=D0=B4=D0=BF= =D0=B8=D1=81=D0=B0=D0=BD=D1=82=D0=B0 private static final CK_ATTRIBUTE[] certificateTemplate3410_2012_256; static { certificateTemplate3410_2012_256 =3D (CK_ATTRIBUTE[]) (new CK_ATTRI= BUTE()).toArray(3); certificateTemplate3410_2012_256[0].setAttr(new NativeLong( Pkcs11Constants.CKA_CLASS), new NativeLong(Pkcs11Constants.= CKO_CERTIFICATE)); // Class - certificate certificateTemplate3410_2012_256[1].setAttr(new NativeLong( Pkcs11Constants.CKA_CERTIFICATE_TYPE), new NativeLong(Pkcs1= 1Constants.CKC_X_509)); // Certificate type - X.509 certificateTemplate3410_2012_256[2].setAttr(new NativeLong( Pkcs11Constants.CKA_CERTIFICATE_CATEGORY), new NativeLong(C= onstants.CK_CERTIFICATE_CATEGORY_TOKEN_USER)); // Certificate category - to= ken user } private static CMSSignedData addSignerToCms(CMSSignedData cms) throws CMSException, Exception { =09=09CMSSignedData newCms =3D null; // =D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B0=D0=B5=D0=BC =D0=B8=D0=BD=D1= =82=D0=B5=D1=80=D1=84=D0=B5=D0=B9=D1=81 PKCS#11 =D0=B1=D0=B8=D0=B1=D0=BB=D0= =B8=D0=BE=D1=82=D0=B5=D0=BA=D0=B8 Pkcs11 pkcs11 =3D RtPkcs11Library.getPkcs11Interface(); NativeLong session =3D new NativeLong(Pkcs11Constants.CK_INVALID_HA= NDLE); try { =09=09=09// =D0=98=D0=BD=D0=B8=D1=86=D0=B8=D0=B0=D0=BB=D0=B8=D0=B7=D0=B8=D1= =80=D1=83=D0=B5=D0=BC =D0=B1=D0=B8=D0=B1=D0=BB=D0=B8=D0=BE=D1=82=D0=B5=D0= =BA=D1=83 =D0=B8 =D0=B0=D0=B2=D1=82=D0=BE=D1=80=D0=B8=D0=B7=D0=BE=D0=B2=D1= =8B=D0=B2=D0=B0=D0=B5=D0=BC=D1=81=D1=8F =D0=BD=D0=B0 =D0=BF=D0=B5=D1=80=D0= =B2=D0=BE=D0=BC =D1=82=D0=BE=D0=BA=D0=B5=D0=BD=D0=B5 Pkcs11Operations.initializePkcs11AndLoginToFirstToken(pkcs11, s= ession); System.out.println("Finding signer certificate"); // =D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B0=D0=B5=D0=BC =D1=82=D0= =B5=D0=BB=D0=BE =D1=81=D0=B5=D1=80=D1=82=D0=B8=D1=84=D0=B8=D0=BA=D0=B0=D1= =82=D0=B0 byte[] signerCertificateValue =3D Pkcs11Operations.getFirstCert= ificateValue(pkcs11, session, certificateTemplate3410_2012_256); Util.printString("Certificate value in PEM:", Util.certificateT= oPem(signerCertificateValue)); // =D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B0=D0=B5=D0=BC =D0=B8=D0= =B4=D0=B5=D0=BD=D1=82=D0=B8=D1=84=D0=B8=D0=BA=D0=B0=D1=82=D0=BE=D1=80 =D0= =B7=D0=B0=D0=BA=D1=80=D1=8B=D1=82=D0=BE=D0=B3=D0=BE =D0=BA=D0=BB=D1=8E=D1= =87=D0=B0 NativeLong signerPrivateKey =3D Pkcs11Operations.getPrivateKeyB= yCertificateValue(pkcs11, session, signerCertificateValue); // =D0=BE=D0=B1=D0=BE=D1=80=D0=B0=D1=87=D0=B8=D0=B2=D0=B0=D0=B5= =D0=BC =D1=82=D0=B5=D0=BB=D0=BE =D1=81=D0=B5=D1=80=D1=82=D0=B8=D1=84=D0=B8= =D0=BA=D0=B0=D1=82=D0=B0 =D0=B2 =D0=B8=D0=BD=D1=82=D0=B5=D1=80=D1=84=D0=B5= =D0=B9=D1=81 Bouncy Castle System.out.println("Creating attached CMS signature via Bouncy = Castle"); X509CertificateHolder certificate =3D new X509CertificateHolder= (signerCertificateValue); // =D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B0=D0=B5=D0=BC =D0=B4=D0= =B0=D0=BD=D0=BD=D1=8B=D0=B5 =D0=B4=D0=BB=D1=8F =D0=BF=D0=BE=D0=B4=D0=BF=D0= =B8=D1=81=D0=B8 CMSTypedData signedContent =3D cms.getSignedContent(); CMSSignedDataGenerator gen =3D new CMSSignedDataGenerator(); // =D0=B7=D0=B0=D0=BD=D0=BE=D0=B2=D0=BE =D0=BF=D0=BE=D0=B4=D0= =BF=D0=B8=D1=81=D1=8B=D0=B2=D0=B0=D0=B5=D0=BC =D1=8D=D1=82=D0=B8 =D0=B4=D0= =B0=D0=BD=D0=BD=D1=8B=D0=B5 gen.addCertificate(certificate); GostContentSigner gostContentSigner =3D new GostContentSigner(P= kcs11GostSigner.SignAlgorithm.GOSTR3410_2012_256, session.longValue(), sign= erPrivateKey.longValue()); gen.addSignerInfoGenerator(new SignerInfoGeneratorBuilder(gostC= ontentSigner.getDigestCalculatorProvider()).build(gostContentSigner, certif= icate)); CMSSignedData newCms =3D gen.generate(signedContent, false); } finally { Pkcs11Operations.logoutAndFinalizePkcs11Library(pkcs11, session= ); } =09 =20 =09=09if (newCms =3D=3D null) { return null; } =09=09 =09=09// =D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B0=D0=B5=D0=BC =D1=81=D1=82=D1= =80=D1=83=D0=BA=D1=82=D1=83=D1=80=D1=83, =D1=85=D1=80=D0=B0=D0=BD=D1=8F=D1= =89=D1=83=D1=8E =D0=B8=D0=BD=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=86=D0=B8=D1= =8E =D0=BE =D0=BD=D0=BE=D0=B2=D0=BE=D0=B9 =D0=BF=D0=BE=D0=B4=D0=BF=D0=B8=D1= =81=D0=B8 =09=09Collection<SignerInformation> newSigners =3D newCms.getSignerIn= fos().getSigners(); // =D0=BE=D0=B1=D1=8A=D0=B5=D0=B4=D0=B8=D0=BD=D1=8F=D0=B5=D0=BC Sig= nerInformation if (newSigners !=3D null) { Collection<SignerInformation> signerInfos =3D cms.getSign= erInfos().getSigners(); signerInfos.addAll(newSigners); cms =3D CMSSignedData.replaceSigners(cms, new SignerInformation= Store(signerInfos)); } else { throw new CMSException("Can't merge CMS signatures"); } =09=09// =D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B0=D0=B5=D0=BC =D1=81=D1=82=D1= =80=D1=83=D0=BA=D1=82=D1=83=D1=80=D1=83, =D1=85=D1=80=D0=B0=D0=BD=D1=8F=D1= =89=D1=83=D1=8E =D0=B8=D0=BD=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=86=D0=B8=D1= =8E =D0=BE=D0=B1 =D1=81=D0=B5=D1=80=D1=82=D0=B8=D1=84=D0=B8=D0=BA=D0=B0=D1= =82=D0=B5 =D0=BD=D0=BE=D0=B2=D0=BE=D0=B3=D0=BE =D0=BF=D0=BE=D0=B4=D0=BF=D0= =B8=D1=81=D0=B0=D0=BD=D0=B0 Collection<X509CertificateHolder> newCertificates =3D newCms.= getCertificates().getMatches(null); // =D0=BE=D0=B1=D1=8A=D0=B5=D0=B4=D0=B8=D0=BD=D1=8F=D0=B5=D0=BC Cer= tificates if (newCertificate !=3D null) { Collection<X509CertificateHolder> certificates =3D cms.ge= tCertificates().getMatches(null); certificates.addAll(newCertificates); cms =3D CMSSignedData.replaceCertificatesAndCRLs(cms, new Colle= ctionStore(certificates), null, null); } else { throw new CMSException("Can't merge CMS certificates"); } return cms; } }