Вот моя реализация SignPdf.
Код: Выделить всё
private static void SignPdf(string pdfPath, string signedPdfPath, SmartCardHandler handler, string certificatePath)
{
using (PdfReader reader = new PdfReader(pdfPath))
using (FileStream os = new FileStream(signedPdfPath, FileMode.Create))
{
X509Certificate2 cert = new X509Certificate2(certificatePath);
Org.BouncyCastle.X509.X509Certificate bouncyCert = ConvertToBouncyCastle(cert);
List chain = new List { bouncyCert };
PdfStamper stamper = PdfStamper.CreateSignature(reader, os, '\0');
PdfSignatureAppearance appearance = stamper.SignatureAppearance;
appearance.Reason = "reason";
appearance.Location = "location";
appearance.SetVisibleSignature(new iTextSharp.text.Rectangle(0, 0, 200, 100), 1, "sig");
appearance.Certificate = chain[0];
IExternalSignature external = new SmartCardSignature(handler);
MakeSignature.SignDetached(appearance, external, chain, null, null, null, 0, CryptoStandard.CMS);
}
}
Код: Выделить всё
class SmartCardSignature : IExternalSignature
{
private readonly SmartCardHandler _handler;
public SmartCardSignature(SmartCardHandler handler)
{
_handler = handler;
}
public byte[] Sign(byte[] message)
{
IDigest messageDigest = DigestUtilities.GetDigest(GetHashAlgorithm());
byte[] hash = DigestAlgorithms.Digest(messageDigest, message);
byte[] sendHash = new byte[] { 0x00, 0x2A, 0x90, 0xA0, 0x22, 0x90, 0x20, (byte)hash.Length }.Concat(hash).ToArray();
_handler.SendApduCommand(sendHash);
byte[] getHash = new byte[] { 0x00, 0xC0, 0x00, 0x00, 0x20 };
_handler.SendApduCommand(getHash);
byte[] signApdu = new byte[] { 0x00, 0x2A, 0x9E, 0x9A, 0x00 };
byte[] signatureWith9000 = _handler.SendApduCommand(signApdu);;
if (signatureWith9000.Length < 2 || signatureWith9000[^2] != 0x90 || signatureWith9000[^1] != 0x00)
{
throw new InvalidOperationException("Failed to sign the message using the smart card.");
}
byte[] signature = signatureWith9000.Take(signatureWith9000.Length - 2).ToArray();
return signature;
}
public string GetHashAlgorithm() => "SHA-256";
public string GetEncryptionAlgorithm() => "RSA";
}
и вот пример PDF-файла, подписанного cms
и вот пример Кадес (не уверен) подписанный pdf
вот трассировка apdu, пин-код 1111
Код: Выделить всё
00 A4 04 00 0C A0 00 00 00 18 40 00 00 01 63 42 00
90 00
00 20 00 81 08 31 31 31 31 30 30 30 30
90 00
00 22 41 B6 06 84 01 02 80 01 42
90 00
00 2A 90 A0 22 90 20 20 0B 2D C2 F7 37 64 BE 40 F9 F3 4C 33 F9 BA F5 4E 49 06 4D 63 C1 B7 CA 51 DD 19 46 08 21 C7 AC 90
61 20
00 C0 00 00 20
20 0B 2D C2 F7 37 64 BE 40 F9 F3 4C 33 F9 BA F5 4E 49 06 4D 63 C1 B7 CA 51 DD 19 46 08 21 C7 AC 90 00
00 2A 9E 9A 00
00 36 F6 C6 9F 0D 40 E7 BC 1E 6C 0D 5F 50 00 DF 3C 26 7F D0 2F F3 95 4C C7 FD E6 18 E5 3E 94 82 4A D1 46 02 65 30 E7 1D 29 9D B7 6F 55 9E B8 49 11 63 16 8E C0 CB E8 44 0B 71 31 9F FB D5 2B 6E 70 DE 30 F7 7F C4 E8 57 EC 39 2A BB 4E 02 AD 92 70 5B DE 23 EB 99 AA FA E1 5F 9E 25 39 0A 39 C2 4F 41 87 82 98 6F 26 2E 5A 8E A2 E5 12 8C 70 41 00 9E 46 4D 9B 18 5D 52 7E 77 9B 16 F3 2A BC 2A 11 FB 53 76 81 8F B7 0C 5F BA 2F A0 A9 9A F2 75 45 78 D0 69 83 3D 05 78 32 68 99 8F 9F B9 14 26 6E 05 06 58 13 D4 7E 98 A2 51 02 F4 81 05 0A F0 DB 0E 8B BB DA C8 6C 56 E7 28 80 A3 DC 12 13 62 E0 CB AA 7B 44 0A E4 44 32 3F 33 8F 31 30 44 E2 EB 00 6F BF F0 42 03 4A AD 15 80 76 97 2E B5 14 B6 CA D0 37 3D E0 67 4A AB A0 96 66 59 85 65 F8 11 C6 B4 64 03 0F 65 78 C8 3B B4 00 58 6D 35 F3 90 00
Подробнее здесь: https://stackoverflow.com/questions/785 ... sharp-5-gi