Статус: Новичок
Группы: Участники
Зарегистрирован: 03.11.2016(UTC) Сообщений: 3  Откуда: Москва Сказал(а) «Спасибо»: 1 раз
|
Добрый день! Столкнулись с проблемой: при шифровании файла, в его начало записывается не нужная нам информация о сертификате, может кто то сталкивался с подобным и знает решение? Версия JCP 2.0.37985
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 06.12.2008(UTC) Сообщений: 4,039  Откуда: Крипто-Про Сказал(а) «Спасибо»: 21 раз Поблагодарили: 731 раз в 689 постах
|
Здравствуйте. Что за информация? Как шифруете данные? |
|
|
|
|
Статус: Новичок
Группы: Участники
Зарегистрирован: 03.11.2016(UTC) Сообщений: 3  Откуда: Москва Сказал(а) «Спасибо»: 1 раз
|
Очень похоже что информация об издателе сертификата, шифруем xml файлы, еще как то можно вначале эту инфу отрезать после расшифровки, при шифровании бинарника такой номер не проходит, вот код сервиса что не так: Код:
package ru.tersys.newhope.encryption.endpoint;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Random;
import javax.crypto.Cipher;
import javax.crypto.KeyAgreement;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.security.auth.x500.X500Principal;
import java.security.Signature;
import com.objsys.asn1j.runtime.Asn1BerDecodeBuffer;
import com.objsys.asn1j.runtime.Asn1BerEncodeBuffer;
import com.objsys.asn1j.runtime.Asn1Null;
import com.objsys.asn1j.runtime.Asn1ObjectIdentifier;
import com.objsys.asn1j.runtime.Asn1OctetString;
import ru.CryptoPro.JCP.ASN.CryptographicMessageSyntax.*;
import ru.CryptoPro.JCP.ASN.Gost28147_89_EncryptionSyntax.Gost28147_89_EncryptedKey;
import ru.CryptoPro.JCP.ASN.Gost28147_89_EncryptionSyntax.Gost28147_89_IV;
import ru.CryptoPro.JCP.ASN.Gost28147_89_EncryptionSyntax.Gost28147_89_ParamSet;
import ru.CryptoPro.JCP.ASN.Gost28147_89_EncryptionSyntax.Gost28147_89_Parameters;
import ru.CryptoPro.JCP.ASN.Gost28147_89_EncryptionSyntax._Gost28147_89_EncryptionSyntaxValues;
import ru.CryptoPro.JCP.ASN.GostR3410_EncryptionSyntax.GostR3410_KeyTransport;
import ru.CryptoPro.JCP.ASN.GostR3410_EncryptionSyntax.GostR3410_TransportParameters;
import ru.CryptoPro.JCP.ASN.PKIX1Explicit88.AlgorithmIdentifier;
import ru.CryptoPro.JCP.ASN.PKIX1Explicit88.Certificate;
import ru.CryptoPro.JCP.ASN.PKIX1Explicit88.CertificateSerialNumber;
import ru.CryptoPro.JCP.ASN.PKIX1Explicit88.Name;
import ru.CryptoPro.JCP.ASN.PKIX1Explicit88.RDNSequence;
import ru.CryptoPro.JCP.ASN.PKIX1Explicit88.SubjectPublicKeyInfo;
import ru.CryptoPro.JCP.JCP;
import ru.CryptoPro.JCP.params.*;
import ru.tersys.newhope.encryption.Config;
@SuppressWarnings("restriction")
public class EncryptWSImpl implements EncryptWS {
protected static final String CIPHER_MODE = "GOST28147/CFB/NoPadding";
//OID алгоритма хеширования.
protected static final String DIGEST_OID = JCP.GOST_DIGEST_OID;
//OID алгоритма подписи.
protected static final String SIGN_OID = JCP.GOST_EL_KEY_OID;
//Алгоритм подписи.
protected static final String SIGN_ALG_NAME = JCP.GOST_EL_SIGN_NAME;
//Алгоритм согласования.
protected static final String KEY_ALG_NAME = JCP.GOST_EL_DH_NAME;
protected static final String SEC_KEY_ALG_NAME = "GOST28147";
protected static final String STR_CMS_OID_DATA = "1.2.840.113549.1.7.1";
protected static final String STR_CMS_OID_SIGNED = "1.2.840.113549.1.7.2";
protected static final String STR_CMS_OID_ENVELOPED = "1.2.840.113549.1.7.3";
@Override
public byte[] encrypt(byte[] data, byte[] publicCertFileBytes) throws Exception {
try {
final KeyStore imageStore = KeyStore.getInstance(Config.getKeyStore());
imageStore.load(null, null);
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
InputStream inStream = new ByteArrayInputStream(publicCertFileBytes);
ParamsInterface crp_params = AlgIdSpec.getDefaultCryptParams();
//генерация случайной синхропосылки
byte[] sv = generateNewSyncro();
//ключ отправителя
final X509Certificate publicSenderCert = (X509Certificate) imageStore.getCertificate(Config.getCertAlias());
final PrivateKey senderKey = (PrivateKey) imageStore.getKey(Config.getCertAlias(), Config.getCertPassword().toCharArray());
//ключ получателя
X509Certificate publicCert = (X509Certificate)certFactory.generateCertificate(inStream);
inStream.close();
//создание SignedData
final ContentInfo contentSign = new ContentInfo();
contentSign.contentType = new Asn1ObjectIdentifier(new OID(STR_CMS_OID_SIGNED).value);
final SignedData signedData = new SignedData();
contentSign.content = signedData;
signedData.version = new CMSVersion(1);
//digest
signedData.digestAlgorithms = new DigestAlgorithmIdentifiers(1);
final DigestAlgorithmIdentifier a = new DigestAlgorithmIdentifier(new OID(DIGEST_OID).value);
a.parameters = new Asn1Null();
signedData.digestAlgorithms.elements[0] = a;
signedData.encapContentInfo = new EncapsulatedContentInfo(new Asn1ObjectIdentifier(
new OID(STR_CMS_OID_DATA).value),
new Asn1OctetString(data));
//certificates
signedData.certificates = new CertificateSet(1);
signedData.certificates.elements = new CertificateChoices[1];
final Certificate certificate = new Certificate();
final Asn1BerDecodeBuffer decodeBuffer = new Asn1BerDecodeBuffer(publicSenderCert.getEncoded());
certificate.decode(decodeBuffer);
signedData.certificates.elements[0] = new CertificateChoices();
signedData.certificates.elements[0].set_certificate(certificate);
//Signature.getInstance
final Signature signature = Signature.getInstance(SIGN_ALG_NAME);
//signer infos
signedData.signerInfos = new SignerInfos(1);
signature.initSign(senderKey);
signature.update(data);
final byte[] sign = signature.sign();
signedData.signerInfos.elements[0] = new SignerInfo();
signedData.signerInfos.elements[0].version = new CMSVersion(1);
signedData.signerInfos.elements[0].sid = new SignerIdentifier();
final byte[] encodedName = publicSenderCert.getIssuerX500Principal().getEncoded();
final Asn1BerDecodeBuffer nameBuf = new Asn1BerDecodeBuffer(encodedName);
final Name name = new Name();
name.decode(nameBuf);
final CertificateSerialNumber num = new CertificateSerialNumber(publicSenderCert.getSerialNumber());
signedData.signerInfos.elements[0].sid.set_issuerAndSerialNumber(new IssuerAndSerialNumber(name, num));
signedData.signerInfos.elements[0].digestAlgorithm = new DigestAlgorithmIdentifier(new OID(DIGEST_OID).value);
signedData.signerInfos.elements[0].digestAlgorithm.parameters = new Asn1Null();
signedData.signerInfos.elements[0].signatureAlgorithm = new SignatureAlgorithmIdentifier(new OID(SIGN_OID).value);
signedData.signerInfos.elements[0].signatureAlgorithm.parameters = new Asn1Null();
signedData.signerInfos.elements[0].signature = new SignatureValue(sign);
//encode
final Asn1BerEncodeBuffer asnBuf = new Asn1BerEncodeBuffer();
contentSign.encode(asnBuf, true);
//данные для envelopedData
final byte[] buffer = asnBuf.getMsgCopy();
//===============================
final PublicKey responderPublic = publicCert.getPublicKey();
//выработка ключа согласования отправителем
final KeyAgreement senderKeyAgree = KeyAgreement.getInstance(KEY_ALG_NAME);
senderKeyAgree.init(senderKey, new IvParameterSpec(sv), null);
senderKeyAgree.doPhase(responderPublic, true);
final SecretKey alisaSecret = senderKeyAgree.generateSecret(SEC_KEY_ALG_NAME);
//Генерирование симметричного ключа с параметрами шифрования из контрольной панели.
final KeyGenerator kg = KeyGenerator.getInstance(SEC_KEY_ALG_NAME);
kg.init(/*paramss*/ crp_params);
final SecretKey simm = kg.generateKey();
//Зашифрование текста на симметричном ключе.
final Cipher cipher = Cipher.getInstance(CIPHER_MODE);
cipher.init(Cipher.ENCRYPT_MODE, simm, (SecureRandom) null);
final byte[] iv = cipher.getIV();
final byte[] text = cipher.doFinal(buffer, 0, buffer.length);
//Зашифрование симметричного ключа на ключе согласования отправителя
cipher.init(Cipher.WRAP_MODE, alisaSecret, (SecureRandom) null);
final byte[] key = cipher.wrap(simm);
//формирование CMS-сообщения
final ContentInfo all = new ContentInfo();
all.contentType = new Asn1ObjectIdentifier(new OID(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(publicSenderCert.getPublicKey().getEncoded());
spki.decode(dbuff);
dbuff.reset();
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 = publicCert.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(publicCert.getSerialNumber());
keytrans.rid.set_issuerAndSerialNumber(issuer);
dbuf.reset();
final GostR3410_KeyTransport encrKey = new GostR3410_KeyTransport();
dbuf = new Asn1BerDecodeBuffer(key);
encrKey.sessionEncryptedKey = new Gost28147_89_EncryptedKey();
encrKey.sessionEncryptedKey.decode(dbuf);
dbuf.reset();
encrKey.transportParameters = new GostR3410_TransportParameters();
encrKey.transportParameters.encryptionParamSet = new Gost28147_89_ParamSet(algid.getCryptParams().getOID().value);
encrKey.transportParameters.ephemeralPublicKey = new SubjectPublicKeyInfo();
dbuf = new Asn1BerDecodeBuffer(publicSenderCert.getPublicKey().getEncoded());
encrKey.transportParameters.ephemeralPublicKey.decode(dbuf);
dbuf.reset();
encrKey.transportParameters.ukm = new Asn1OctetString(sv);
encrKey.encode(ebuf);
keytrans.encryptedKey = new EncryptedKey(ebuf.getMsgCopy());
ebuf.reset();
cms.recipientInfos.elements[0].set_ktri(keytrans);
cms.encryptedContentInfo = new EncryptedContentInfo();
final OID contentType = new OID(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(crp_params.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();
}
catch (Throwable t) {
t.printStackTrace();
throw t;
}
}
private byte[] generateNewSyncro() {
final Random rnd = new Random();
final byte[] syncro = new byte[8];
for (int j = 0; j < 8; j++) syncro[j] = (byte) rnd.nextInt();
return syncro;
}
}
Отредактировано пользователем 3 ноября 2016 г. 16:49:36(UTC)
| Причина: Не указана
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 06.12.2008(UTC) Сообщений: 4,039  Откуда: Крипто-Про Сказал(а) «Спасибо»: 21 раз Поблагодарили: 731 раз в 689 постах
|
Нужно использовать эфемерный ключ вместо долговременного ключа отправителя. Посмотрите пример PKCS7EnvEphTransport в пакете CMS_samples (samples-sources.jar). |
|
|
|
|
Статус: Новичок
Группы: Участники
Зарегистрирован: 03.11.2016(UTC) Сообщений: 3  Откуда: Москва Сказал(а) «Спасибо»: 1 раз
|
Спасибо за ответ. А я правильно понимаю что для зашифровывания не используется закрытый ключ (private key) отправителя?
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 06.12.2008(UTC) Сообщений: 4,039  Откуда: Крипто-Про Сказал(а) «Спасибо»: 21 раз Поблагодарили: 731 раз в 689 постах
|
Автор: Toryn  Спасибо за ответ. А я правильно понимаю что для зашифровывания не используется закрытый ключ (private key) отправителя? Да, используется временный эфемерный ключ и открытый ключ получателя. Получатель затем с помощью своего закрытого ключа и ключа из сообщения расшифрует его. |
|
 1 пользователь поблагодарил Евгений Афанасьев за этот пост.
|
Toryn оставлено 08.11.2016(UTC)
|
|
Быстрый переход
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.
Important Information:
The Форум КриптоПро uses cookies. By continuing to browse this site, you are agreeing to our use of cookies.
More Details
Close