Добрый день.
Подскажите, пожалуйста.
Реализую схему подписи на клиенте через КриптоПро Browser Plugin.
На сервере использую itextpdf.
Создаю pdf с пустым контейнером для подписи. Отдаю клиенту на подпись данные в Base64.
Код:
ByteArrayOutputStream os = new ByteArrayOutputStream();
byte[] b = bytesByFile(is);
PdfReader reader = new PdfReader(b);
PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0');
PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
appearance.setVisibleSignature(new com.itextpdf.text.Rectangle(36, 748, 144, 780), 1, signatureFieldNam);
ExternalSignatureContainer external = new ExternalBlankSignatureContainer(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED);
MakeSignature.signExternalContainer(appearance, external, 8192);
byte[] data = IOUtils.toByteArray(appearance.getRangeStream());
return Base64.getEncoder().encodeToString(data);
На клиенте вычисляю хэш и подписываю его:
Код:
function createSign(dataToSign, selectedCertID){
// Получаю нужный сертификат
var thumbprint = e.options[selectedCertID].value.split(" ").reverse().join("").replace(/\s/g, "").toUpperCase();
try {
var oStore = yield cadesplugin.CreateObjectAsync("CAdESCOM.Store");
yield oStore.Open();
var all_certs = yield oStore.Certificates;
var oCerts = yield all_certs.Find(cadesplugin.CAPICOM_CERTIFICATE_FIND_SHA1_HASH, thumbprint);
if ((yield oCerts.Count) == 0) {
alert("Certificate not found");
return;
}
var certificate = yield oCerts.Item(1);
} catch (err) {
alert('Certificate not found');
return;
}
// Хэшируем. Используем CADESCOM_BASE64_TO_BINARY, поэтому оставляем пришедший base64
try {
var oHashedData = yield cadesplugin.CreateObjectAsync('CAdESCOM.HashedData');
yield oHashedData.propset_Algorithm(cadesplugin.CADESCOM_HASH_ALGORITHM_CP_GOST_3411);
yield oHashedData.propset_DataEncoding = cadesplugin.CADESCOM_BASE64_TO_BINARY;
yield oHashedData.Hash(dataToSign);
} catch (err) {
throw "Failed to create CAdESCOM.HashedData: " + err.number;
}
// подписчик
try {
var oSigner = yield cadesplugin.CreateObjectAsync("CAdESCOM.CPSigner");
yield oSigner.propset_Certificate(certificate);
} catch (err) {
throw "Failed to create CAdESCOM.CPSigner: " + err.number;
}
// Подписываю хэш. Получаю base64 - отдаю его на сервер для дальнейшей вставки
var oSignedData = yield cadesplugin.CreateObjectAsync("CAdESCOM.CadesSignedData");
if (dataToSign) {
try {
yield oSignedData.propset_DataEncoding = cadesplugin.CADESCOM_BASE64_TO_BINARY;
var Signature = yield oSignedData.SignHash(oHashedData, oSigner, cadesplugin.CADESCOM_CADES_BES);
return Signature;
} catch (err) {
throw "Не удалось создать подпись из-за ошибки: " + cadesplugin.getLastError(err);
}
}
}
Если проверить через yield oSignedData.VerifyHash - все норм.
С клиента приходит Base64. На сервере вставляю подпись в пустой ранее контейнер:
Код:
public byte[] sign(FileId fileId, byte[] signature, String signatureFieldNam) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try {
byte[] file = getContent(fileId).orElseThrow(() -> new FileNotFoundException(fileId));
PdfReader reader = new PdfReader(file);
ExternalSignatureContainer container = new BrowserSignatureContainer(signature);
MakeSignature.signDeferred(reader, signatureFieldNam, outputStream, container);
return outputStream.toByteArray();
} catch (IOException | GeneralSecurityException | DocumentException e) {
log.error("while sign pdf file by external signature", e);
throw new Exception("");
} finally {
try {
outputStream.close();
} catch (IOException e) {
// Ignore
}
}
}
class BrowserSignatureContainer implements ExternalSignatureContainer {
private byte[] sinedData;
public BrowserSignatureContainer(byte[] signature) {
this.sinedData = Base64.getDecoder().decode(signature);
}
public byte[] sign(InputStream is) {
return sinedData;
}
public void modifySigningDictionary(PdfDictionary pdfDictionary) {
}
}
Но подпись в Adobe Acrobat XI Pro не распознается.
Пишет "Ошибка при подтверждении подписи.
Ошибка при проверке:
Неподдерживаемый алгоритм"
Хотя если подписать прямо в Adobe Acrobat XI Pro этим же сертификатом- все нормально, подпись распознается.
Что-то делаю не так?
Судя по сравнению моего файла pdf (подписанного через браузер) и файла, подписанного через Adobe Acrobat XI Pro - они отличаются.
Подпись, что получаю через плагин:
MIIFxwYJKoZIhvcNAQcCoIIFuDCCBbQCAQExDDAKBgYqhQMCAgkFADALBgkqhkiG9w0BBwGgggMu
MIIDKjCCAtmgAwIBAgITEgAsOFQWlMsYXkwr7gAAACw4VDAIBgYqhQMCAgMwfzEjMCEGCSqGSIb3
DQEJARYUc3VwcG9ydEBjcnlwdG9wcm8ucnUxCzAJBgNVBAYTAlJVMQ8wDQYDVQQHEwZNb3Njb3cx
FzAVBgNVBAoTDkNSWVBUTy1QUk8gTExDMSEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVy
IDIwHhcNMTgwODIyMTM1NjE2WhcNMTgxMTIyMTQwNjE2WjA5MR8wHQYJKoZIhvcNAQkBFhBtYXNr
X2JlbEBtYWlsLnJ1MQowCAYDVQQDDAFNMQowCAYDVQQKDAFNMGMwHAYGKoUDAgITMBIGByqFAwIC
JAAGByqFAwICHgEDQwAEQGbbKsLP1NizExIOFnIM1BpRymkWDkAGLGjLMuhIDi598clA/xWSnRCC
5OU7e/3t2FRf2l9heNEs+HvFNRjhTy+jggFwMIIBbDAOBgNVHQ8BAf8EBAMCBPAwEwYDVR0lBAww
CgYIKwYBBQUHAwIwHQYDVR0OBBYEFDPZYK4dienvocZVEnL5RSOXAyx3MB8GA1UdIwQYMBaAFBUx
fLCNGt5m1xWcSVKXFyS5AXqDMFkGA1UdHwRSMFAwTqBMoEqGSGh0dHA6Ly90ZXN0Y2EuY3J5cHRv
cHJvLnJ1L0NlcnRFbnJvbGwvQ1JZUFRPLVBSTyUyMFRlc3QlMjBDZW50ZXIlMjAyLmNybDCBqQYI
KwYBBQUHAQEEgZwwgZkwYQYIKwYBBQUHMAKGVWh0dHA6Ly90ZXN0Y2EuY3J5cHRvcHJvLnJ1L0Nl
cnRFbnJvbGwvdGVzdC1jYS0yMDE0X0NSWVBUTy1QUk8lMjBUZXN0JTIwQ2VudGVyJTIwMi5jcnQw
NAYIKwYBBQUHMAGGKGh0dHA6Ly90ZXN0Y2EuY3J5cHRvcHJvLnJ1L29jc3Avb2NzcC5zcmYwCAYG
KoUDAgIDA0EA/A/uNOkkJRaATjSRGLyYAoepiVaDO2MbMd74kiyj6t+VLxJS561lgnHbQxXdp0PK
YwTrBemCAOcZ8w99HMon/TGCAmAwggJcAgEBMIGWMH8xIzAhBgkqhkiG9w0BCQEWFHN1cHBvcnRA
Y3J5cHRvcHJvLnJ1MQswCQYDVQQGEwJSVTEPMA0GA1UEBxMGTW9zY293MRcwFQYDVQQKEw5DUllQ
VE8tUFJPIExMQzEhMB8GA1UEAxMYQ1JZUFRPLVBSTyBUZXN0IENlbnRlciAyAhMSACw4VBaUyxhe
TCvuAAAALDhUMAoGBiqFAwICCQUAoIIBUDAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqG
SIb3DQEJBTEPFw0xODA4MjYxNzAxMDJaMC8GCSqGSIb3DQEJBDEiBCBDTphHq50wH+WVLxw0BQ7q
n9t2Vt5oa/UQm3XGmm/HpDCB5AYLKoZIhvcNAQkQAi8xgdQwgdEwgc4wgcswCAYGKoUDAgIJBCC0
qDGWTfR/tASWHFUZSOnI6AA0GEZnYQ5R4jH2mEdmTTCBnDCBhKSBgTB/MSMwIQYJKoZIhvcNAQkB
FhRzdXBwb3J0QGNyeXB0b3Byby5ydTELMAkGA1UEBhMCUlUxDzANBgNVBAcTBk1vc2NvdzEXMBUG
A1UEChMOQ1JZUFRPLVBSTyBMTEMxITAfBgNVBAMTGENSWVBUTy1QUk8gVGVzdCBDZW50ZXIgMgIT
EgAsOFQWlMsYXkwr7gAAACw4VDAcBgYqhQMCAhMwEgYHKoUDAgIkAAYHKoUDAgIeAQRAVMZaave5
IW7zfeYgTDr9IwxcYcCwbumNBAMe1Gk2N8Wh3Mm2YDg/qRC7frQOGJonHR1hy1ouQ7PBmMS+weIU
sQ==
Верно ли я понимаю, что нужно выкинуть переносы строк и раскодировать из base64 на сервере?
Отредактировано пользователем 27 августа 2018 г. 14:46:00(UTC)
| Причина: Не указана