Статус: Участник
Группы: Участники
Зарегистрирован: 03.07.2018(UTC) Сообщений: 17 ![Российская Федерация Российская Федерация](/forum2/Content/images/flags/RU.png) Откуда: Москва
|
Шифруем мы следующим образом Код:
public class EncryptService {
public byte[] encrypt(X509Certificate recipientCert, Path fileToEncrypt) throws Exception {
byte[] data = Files.readAllBytes(fileToEncrypt);
final PublicKey recipientPublic = recipientCert.getPublicKey();
// Генерирование симметричного ключа с параметрами
// шифрования из контрольной панели.
final KeyGenerator kg = KeyGenerator.getInstance(CryptoUtil.GOST28147, CryptoProvider.PROVIDER_NAME);
final ParamsInterface paramss = AlgIdSpec.getDefaultCryptParams();
kg.init(paramss);
final SecretKey simm = kg.generateKey();
// Зашифрование текста на симметричном ключе.
Cipher cipher = Cipher.getInstance(CryptoUtil.CIPHER_MODE, CryptoProvider.PROVIDER_NAME);
cipher.init(Cipher.ENCRYPT_MODE, simm, (SecureRandom) null);
final byte[] iv = cipher.getIV();
final byte[] text = cipher.doFinal(data, 0, data.length);
// Зашифрование симметричного ключа.
final byte[] keyTransport = wrap(simm, recipientPublic);
// Формирование CMS-сообщения.
final ContentInfo all = new ContentInfo();
all.contentType = new Asn1ObjectIdentifier(new OID(CryptoUtil.STR_CMS_OID_ENVELOPED).value);
final EnvelopedData cms = new EnvelopedData();
all.content = cms;
cms.version = new CMSVersion(0);
cms.recipientInfos = new RecipientInfos(1);
cms.recipientInfos.elements = new RecipientInfo[1];
cms.recipientInfos.elements[0] = new RecipientInfo();
final KeyTransRecipientInfo keytrans = new KeyTransRecipientInfo();
keytrans.version = new CMSVersion(0);
final Asn1BerEncodeBuffer ebuf = new Asn1BerEncodeBuffer();
final SubjectPublicKeyInfo spki = new SubjectPublicKeyInfo();
final Asn1BerDecodeBuffer dbuff = new Asn1BerDecodeBuffer(
recipientPublic.getEncoded());
spki.decode(dbuff);
dbuff.reset();
// final AlgIdInterface algid = new AlgIdSpec(JCP.GOST_EL_KEY_OID);
final AlgIdInterface algid = new AlgIdSpec(spki.algorithm);
final AlgorithmIdentifier id = (AlgorithmIdentifier) algid.getDecoded();
id.encode(ebuf);
Asn1BerDecodeBuffer dbuf = new Asn1BerDecodeBuffer(ebuf.getMsgCopy());
keytrans.keyEncryptionAlgorithm = new KeyEncryptionAlgorithmIdentifier();
keytrans.keyEncryptionAlgorithm.decode(dbuf);
ebuf.reset();
dbuf.reset();
keytrans.rid = new RecipientIdentifier();
final IssuerAndSerialNumber issuer = new IssuerAndSerialNumber();
final X500Principal issuerName = recipientCert.getIssuerX500Principal();
dbuf = new Asn1BerDecodeBuffer(issuerName.getEncoded());
issuer.issuer = new Name();
final RDNSequence rnd = new RDNSequence();
rnd.decode(dbuf);
issuer.issuer.set_rdnSequence(rnd);
issuer.serialNumber = new CertificateSerialNumber(recipientCert.getSerialNumber());
keytrans.rid.set_issuerAndSerialNumber(issuer);
dbuf.reset();
keytrans.encryptedKey = new EncryptedKey(keyTransport);
ebuf.reset();
cms.recipientInfos.elements[0].set_ktri(keytrans);
cms.encryptedContentInfo = new EncryptedContentInfo();
final OID contentType = new OID(CryptoUtil.STR_CMS_OID_DATA);
cms.encryptedContentInfo.contentType = new ContentType(contentType.value);
final Gost28147_89_Parameters params = new Gost28147_89_Parameters();
params.iv = new Gost28147_89_IV(iv);
params.encryptionParamSet = new Gost28147_89_ParamSet(paramss.getOID().value);
cms.encryptedContentInfo.contentEncryptionAlgorithm = new ContentEncryptionAlgorithmIdentifier(
_Gost28147_89_EncryptionSyntaxValues.id_Gost28147_89, params);
cms.encryptedContentInfo.encryptedContent = new EncryptedContent(text);
all.encode(ebuf);
return ebuf.getMsgCopy();
}
/**
* Зашифрование сессионного ключа.
*
* @param secretKey Сессионный ключ.
* @param recipientKey Открытый ключ получателя.
* @return транспортная структура GostR3410_KeyTransport.
* @throws Exception
*/
private byte[] wrap(SecretKey secretKey, Key recipientKey) throws Exception {
// Генерация эфемерной пары.
KeyPairGenerator kgp = KeyPairGenerator.getInstance(
JCP.GOST_EPH_DH_2012_512_NAME,
CryptoProvider.PROVIDER_NAME
);
// Устанавливаем нужные параметры, как у получателя.
GostPublicKey repPublicKey = (GostPublicKey) recipientKey;
ParamsInterface repPublicKeySpec = repPublicKey.getSpec().getParams();
kgp.initialize(repPublicKeySpec);
// Генерируем эфемерную пару.
KeyPair ephPair = kgp.generateKeyPair();
PrivateKey privateKey = ephPair.getPrivate();
PublicKey publicKey = ephPair.getPublic();
byte[] syncro = new byte[8];
SecureRandom random = SecureRandom.getInstance(JCP.CP_RANDOM, JCP.PROVIDER_NAME);
random.nextBytes(syncro);
IvParameterSpec iv = new IvParameterSpec(syncro);
OID oid = CryptParamsSpec.OID_Crypt_VerbaO;
// Выработка ключа согласования.
KeyAgreement ka = KeyAgreement.getInstance(privateKey.getAlgorithm(), CryptoProvider.PROVIDER_NAME);
ka.init(privateKey, iv);
ka.doPhase(recipientKey, true);
Key dh = ka.generateSecret(CryptoUtil.GOST28147);
//Зашифрование симметричного ключа на ключе согласования
// отправителя.
final Cipher cipher = Cipher.getInstance(CryptoUtil.GOST28147, CryptoProvider.PROVIDER_NAME);
cipher.init(Cipher.WRAP_MODE, dh, (SecureRandom) null);
final byte[] wrappedKey = cipher.wrap(secretKey);
// Упаковка параметров и ключа.
Gost28147_89_EncryptedKey encryptedKey = new Gost28147_89_EncryptedKey();
Asn1BerDecodeBuffer decoder = new Asn1BerDecodeBuffer(wrappedKey);
encryptedKey.decode(decoder);
byte[] imita = encryptedKey.macKey.value;
byte[] wrapperKeyBytes = encryptedKey.encryptedKey.value;
// Кодирование открытого ключа в SubjectPublicKeyInfo.
byte[] publicKeyBytes = publicKey.getEncoded();
SubjectPublicKeyInfo publicKeyInfo = new SubjectPublicKeyInfo();
decoder = new Asn1BerDecodeBuffer(publicKeyBytes);
publicKeyInfo.decode(decoder);
// Кодирование GostR3410_KeyTransport.
GostR3410_KeyTransport keyTransport = new GostR3410_KeyTransport();
Asn1BerEncodeBuffer encoder = new Asn1BerEncodeBuffer();
keyTransport.sessionEncryptedKey = new Gost28147_89_EncryptedKey(wrapperKeyBytes, imita);
keyTransport.transportParameters = new GostR3410_TransportParameters(
new Gost28147_89_ParamSet(oid.value),
publicKeyInfo,
new Asn1OctetString(iv.getIV()));
keyTransport.encode(encoder);
return encoder.getMsgCopy();
}
}
Сигнатуру получаем следующим образом: Код:
public class SignatureService {
public byte[] signDetached(Path originalFilePath, PrivateKey privateKey, X509Certificate certificate) throws Exception {
byte[] data = Files.readAllBytes(originalFilePath);
Signature signature = Signature.getInstance(JCP.GOST_SIGN_2012_512_NAME);
signature.initSign(privateKey);
signature.update(data);
return createCMSEx(data, signature.sign(), certificate, true);
}
public byte[] sign(Path originalFilePath, PrivateKey privateKey, X509Certificate certificate) throws Exception {
byte[] data = Files.readAllBytes(originalFilePath);
Signature signature = Signature.getInstance(JCP.GOST_SIGN_2012_512_NAME);
signature.initSign(privateKey);
signature.update(data);
return createCMSEx(data, signature.sign(), certificate, false);
}
public byte[] readAndVerify(byte[] bytes, X509Certificate cert) {
return propagateCatchableException(() -> {
CMSSignedData data = new CMSSignedData(bytes);
SignerInformation signer = data.getSignerInfos().getSigners().iterator().next();
JcaSimpleSignerInfoVerifierBuilder builder = new JcaSimpleSignerInfoVerifierBuilder();
SignerInformationVerifier verifier = builder.build(cert);
if (!signer.verify(verifier)) {
throw new Exception("Data is compromised, wrong signDetached");
}
return (byte[]) data.getSignedContent().getContent();
});
}
public byte[] readNotVerify(byte[] bytes) {
return propagateCatchableException(() -> {
CMSSignedData data = new CMSSignedData(bytes);
return (byte[]) data.getSignedContent().getContent();
});
}
private byte[] createCMSEx(byte[] data, byte[] sign, Certificate cert, boolean detached) throws Exception {
final ContentInfo all = new ContentInfo();
all.contentType = new Asn1ObjectIdentifier(new OID(CryptoUtil.STR_CMS_OID_SIGNED).value);
final SignedData cms = new SignedData();
all.content = cms;
cms.version = new CMSVersion(1);
// digest
cms.digestAlgorithms = new DigestAlgorithmIdentifiers(1);
final DigestAlgorithmIdentifier a = new DigestAlgorithmIdentifier(new OID(JCP.GOST_DIGEST_2012_512_OID).value);
a.parameters = new Asn1Null();
cms.digestAlgorithms.elements[0] = a;
if (detached) {
cms.encapContentInfo = new EncapsulatedContentInfo(
new Asn1ObjectIdentifier(
new OID(CryptoUtil.STR_CMS_OID_DATA).value), null);
} else {
cms.encapContentInfo =
new EncapsulatedContentInfo(new Asn1ObjectIdentifier(
new OID(CryptoUtil.STR_CMS_OID_DATA).value),
new Asn1OctetString(data));
}
// certificate
cms.certificates = new CertificateSet(1);
final ru.CryptoPro.JCP.ASN.PKIX1Explicit88.Certificate certificate = new ru.CryptoPro.JCP.ASN.PKIX1Explicit88.Certificate();
final Asn1BerDecodeBuffer decodeBuffer = new Asn1BerDecodeBuffer(cert.getEncoded());
certificate.decode(decodeBuffer);
cms.certificates.elements = new CertificateChoices[1];
cms.certificates.elements[0] = new CertificateChoices();
cms.certificates.elements[0].set_certificate(certificate);
// signer info
cms.signerInfos = new SignerInfos(1);
cms.signerInfos.elements[0] = new SignerInfo();
cms.signerInfos.elements[0].version = new CMSVersion(1);
cms.signerInfos.elements[0].sid = new SignerIdentifier();
final byte[] encodedName = ((X509Certificate) cert).getIssuerX500Principal().getEncoded();
final Asn1BerDecodeBuffer nameBuf = new Asn1BerDecodeBuffer(encodedName);
final Name name = new Name();
name.decode(nameBuf);
final CertificateSerialNumber num = new CertificateSerialNumber(((X509Certificate) cert).getSerialNumber());
cms.signerInfos.elements[0].sid.set_issuerAndSerialNumber(new IssuerAndSerialNumber(name, num));
cms.signerInfos.elements[0].digestAlgorithm = new DigestAlgorithmIdentifier(new OID(JCP.GOST_DIGEST_2012_512_OID).value);
cms.signerInfos.elements[0].digestAlgorithm.parameters = new Asn1Null();
cms.signerInfos.elements[0].signatureAlgorithm = new SignatureAlgorithmIdentifier(new OID(JCP.GOST_PARAMS_SIG_2012_512_KEY_OID).value);
cms.signerInfos.elements[0].signatureAlgorithm.parameters = new Asn1Null();
cms.signerInfos.elements[0].signature = new SignatureValue(sign);
// encode
final Asn1BerEncodeBuffer asnBuf = new Asn1BerEncodeBuffer();
all.encode(asnBuf, true);
return asnBuf.getMsgCopy();
}
}
Это уже адаптированный код мною по ГОСТ 2012, 512 бит. В атаче исходный файл (данные фейковые) и зашифрованный, что отправляю. ![](/forum2/Themes/soclean/icon_file.gif) B701FF000000_20100901_164556.zip.enc (3kb) загружен 3 раз(а).Сертификат НБКИ, наверное, я не имею права выкладывать.
|