Статус: Новичок
Группы: Участники
Зарегистрирован: 08.07.2021(UTC) Сообщений: 5
Сказал(а) «Спасибо»: 2 раз
|
добрый день. Стоит задача с помощью Java CSP подписывать файлы, например PDF. Подпись требуется открепленная, в формате CMS. Делал по примерам из samples-sources.jar: Код:
public void signPdf(File pdfFile) throws Exception {
KeyStore keyStore = KeyStore.getInstance("HDIMAGE", "JCSP");
keyStore.load(null, null);
PrivateKey privateKey = (PrivateKey) keyStore.getKey(KEY_CONT_ALIAS, PASSWORD);
X509Certificate certificate = (X509Certificate) keyStore.getCertificate(KEY_CONT_ALIAS);
Signature signature = Signature.getInstance(JCP.CRYPTOPRO_SIGN_2012_256_NAME, "JCSP");
signature.initSign(privateKey);
FileInputStream fData = new FileInputStream(new File("testdata/test.pdf"));
int read;
while ((read = fData.read()) != -1) {
signature.update((byte)read);
}
fData.close();
byte[] cms = createCMSEx(null, signature.sign(), certificate, true,
JCP.GOST_DIGEST_OID, JCP.GOST_EL_KEY_OID);
Array.writeFile("testdata/sign.dat", cms);
//проверка подписи
signature = Signature.getInstance(JCP.CRYPTOPRO_SIGN_2012_256_NAME);
signature.initVerify(certificate.getPublicKey());
readAndHash(signature, pdfFile.getAbsolutePath());
verify(cms, certificate, signature);
}
public static byte[] createCMSEx(byte[] buffer, byte[] sign,
Certificate cert, boolean detached, String digestOid,
String signOid) throws Exception {
final ContentInfo all = new ContentInfo();
all.contentType = new Asn1ObjectIdentifier(
new OID("1.2.840.113549.1.7.2").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(digestOid).value);
a.parameters = new Asn1Null();
cms.digestAlgorithms.elements[0] = a;
if (detached) {
cms.encapContentInfo = new EncapsulatedContentInfo(
new Asn1ObjectIdentifier(
new OID("1.2.840.113549.1.7.1").value), null);
} // if
else {
cms.encapContentInfo =
new EncapsulatedContentInfo(new Asn1ObjectIdentifier(
new OID("1.2.840.113549.1.7.1").value),
new Asn1OctetString(buffer));
} // else
// 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(digestOid).value);
cms.signerInfos.elements[0].digestAlgorithm.parameters = new Asn1Null();
cms.signerInfos.elements[0].signatureAlgorithm =
new SignatureAlgorithmIdentifier(new OID(signOid).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();
}
Примеры взял из класса DetachedSignatureFileExample, код метода verify() приводить не буду, так как это не принципиально. Сделал тестовый сертификат в онлайн-сервисе КриптоПРО. Суть в том, что созданная подпись в формате cms при проверке на сайте гос.услуги, а так же в онлайн-сервисе проверки КриптоПРО считается недействительной. По методу verify() взятому из того же класса DetachedSignatureFileExample проверка проходит нормально. Предполагаю, что проблемы связаны с передачей констант в метод createCMSex(), но на 100% не уверен. Во всяком случае, судя по дебаггеру все идет хорошо до вызова этого метода. На всякий случай, ключ со следующими характеристиками: *** Ключ обмена*** ГОСТ Р 34.10-2012 DH 256 бит Неэкспортируемый * Параметры подписи и обмена: ГОСТ Р 34.10 256 бит, параметры обмена по умолчанию * Параметры хэширования: Функция хэширования ГОСТ Р 34.11-2012 (256) * Параметры шифрования: ГОСТ 28147-89, TC 26 параметры шифрования Z Прошу помочь разобраться с данной проблемой, если потребуется - предоставлю дополнительные сведения
|