Poštovanje,
pokušavam digitalno potpisati dokument koristeći FINA timestamp server.
Use case je sljedeći: U foreach petlji pokušam 20-tak puta potpisati dokument. Timestamper objekt se instancira sa ispravnim url i certifikatom za pristup timestamp serveru.
Iz nekog razloga nakon nekoliko uspješnih odgovora FINA počinje vraćati grešku TLS connection could not be established.
Naravno, od FINA-a nema neke pomoći. Ono što su oni uočili jest da se u nekom trenutku prema njima počne slati zahtjev sa TLSv1.3 (Napomena: FINA podržava samo TLSv1.2)
Isti scenarij sam probao sa drugim Timestamp serverima (kvalificiranim i nekvalificiranim) i sve radi uredno.
Također, probao sam instancirati i HttpClient te u foreach petlji pozivati FINA-a timestamp server i to radi bez problema.
Zatim sam pokušao podvaliti svoju implementaciju timestamper objekta ali GetTimestampToken metoda se nikada ne poziva
public class MyTimestamper : PdfTimestamper
{
protected override byte[] GetTimestampToken(Stream content)
{
//implementacija
}
}
Možete li mi pomoći vidjeti što bi bio problem ili omogućiti korištenje vlastite implementacije Timestamper objekta?
Unaprijed zahvaljujem,
Robert
Bok Roberte!
Probajte sa ovom implementacijom:
class PdfSecureTimestamper : PdfTimestamper
{
private readonly System.Net.SecurityProtocolType securityProtocol;
public PdfSecureTimestamper(string address, System.Net.SecurityProtocolType securityProtocol) : base(address)
{
this.securityProtocol = securityProtocol;
}
protected override int EstimatedTimestampTokenLength => base.EstimatedTimestampTokenLength;
protected override byte[] GetTimestampToken(Stream content)
{
var previousSecurityProtocol = System.Net.ServicePointManager.SecurityProtocol;
System.Net.ServicePointManager.SecurityProtocol = this.securityProtocol;
try
{
return base.GetTimestampToken(content);
}
finally
{
System.Net.ServicePointManager.SecurityProtocol = previousSecurityProtocol;
}
}
}
Koristite je kao u primjeru PDF Advanced Electronic Signatures (PAdES) in C# and VB.NET uz ovu promjenu:
signer.Timestamper = new PdfSecureTimestamper("<FINA Time Stamp service address>", System.Net.SecurityProtocolType.Tls12);
Ukoliko želite koristiti u potpunosti vlastitu implementaciju timestamper-a, onda se ova dva člana moraju implementirati:
public class MyTimestamper : PdfTimestamper
{
protected override int EstimatedTimestampTokenLength
{
get
{
// vrati broj koji je uvijek veći od broja byte-ova koje se vrate u metodi GetTimestampToken,
// ali po mogućnosti ne previše veći jer se onda bespotrebno povećava veličina potpisanog PDF dokumenta.
}
}
protected override byte[] GetTimestampToken(Stream content)
{
// implementacija
// Vraćeni broj byte-ova mora uvijek biti manji od EstimatedTimestampTokenLength.
}
}
Ukoliko GemBox.Pdf i dalje ne poziva Vašu implementaciju timestamper-a, molimo da nam pošaljete minimalni Visual Studio projekt koji reproducira problem na Contact Us - GemBox Support Center tako da možemo reproducirati problem na našoj strani, pa ćemo ga istražiti i pokušati riješiti.
Pozdrav,
Stipo
Hvala na brzom odgovoru.
Poslao sam primjer. Reference number: 35069
U suštini radim delay sign i ne radi.
Probao sam na Vašem primjeru i tu radi.
PDF Advanced Electronic Signatures (PAdES) in C# and VB.NET
Hvala
Bok,
malo sam se poigrao sa Timestamperom i čini mi se da Timestamper radi “dummy” request u BeginSign na timestamp server kako bi dohvatio potpis te dužinu potpisa stavio u polje EstimatedTimestampTokenLength.
Tek kod EndSign se zaista dogodi poziv metode GetTimestampToken.
Problem je što pukne “dummy” request na BeginSign dijelu.
Staviti neki fiksni broj u polje EstimatedTimestampTokenLength nije baš sretno rješenje jer dužina može značajno varirati od pružatelja usluga.
Na temelju ovih nagađanja ću probati implementirati svoj timestamper koji će također raditi “dummy” request na timestamp server i postaviti vrijednost u polje EstimatedTimestampTokenLength te implementirati GetTimestampToken
Na žalost nisam uspio.
Ono što mi je zanimljivo je da ovaj segment koda kad se izvšava izvan Timestamper klase radi ali kad ga se postavi unutar getter od EstimatedTimestampTokenLength ili unutar GetTimestampToken metode ne radi tj, dobivam grešku
byte[] nonce = RandomNumberGenerator.GetBytes(32);
Rfc3161TimestampRequest timestampRequest = Rfc3161TimestampRequest.CreateFromData(
data,
hashAlgorithm.Value,
null,
nonce,
true
);
using HttpRequestMessage request = CreateRequest(timestampRequest.Encode());
using HttpClient client = CreateHttpClient();
using HttpResponseMessage response = client.Send(request);
System.Security.Cryptography.CryptographicException:
Internal error occurred while performing cryptographic operation. See inner exception for details.
–>System.Net.WebException: The SSL connection could not be established, see inner exception.
–>System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.
–>System.Security.Authentication.AuthenticationException: Authentication failed, see inner exception.
–>System.ComponentModel.Win32Exception: The Local Security Authority cannot be contacted
Probao sam i eksplicitno postaviti TLSv1.2 na HttpClientHandler i na SocketHandler ali nije pomoglo
HttpClientHandler handler = new();
handler.SslProtocols = System.Security.Authentication.SslProtocols.Tls12;
handler.ClientCertificates.Add(_timestampSourceInfo.ClientId);