I am trying to sign pdf with a smart card. I use the following code:
public class SC {
public static final String SRC = "src/test.pdf";
public static final String DEST = "src/test_smartCard.pdf";
public void sign(String src, String dest,
Certificate[] chain, PrivateKey pk,
String digestAlgorithm, String provider, CryptoStandard subfilter,
String reason, String location,
Collection<CrlClient> crlList,
OcspClient ocspClient,
TSAClient tsaClient,
int estimatedSize)
throws GeneralSecurityException, IOException, DocumentException {
// Creating the reader and the stamper
PdfReader reader = new PdfReader(src);
FileOutputStream os = new FileOutputStream(dest);
PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0');
// Creating the appearance
PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
appearance.setReason(reason);
appearance.setLocation(location);
appearance.setVisibleSignature(new Rectangle(36, 748, 144, 780), 1, "sig");
// Creating the signature
ExternalSignature pks = new PrivateKeySignature(pk, digestAlgorithm, provider);
ExternalDigest digest = new BouncyCastleDigest();
MakeSignature.signDetached(appearance, digest, pks, chain, crlList, ocspClient, tsaClient, estimatedSize, subfilter);
}
public static void main(String[] args) throws IOException, GeneralSecurityException, DocumentException {
LoggerFactory.getInstance().setLogger(new SysoLogger());
BouncyCastleProvider providerBC = new BouncyCastleProvider();
Security.addProvider(providerBC);
SunMSCAPI providerMSCAPI = new SunMSCAPI();
Security.addProvider(providerMSCAPI);
KeyStore ks = KeyStore.getInstance("Windows-MY");
ks.load(null, null);
String alias = (String)ks.aliases().nextElement();
PrivateKey pk = (PrivateKey)ks.getKey(alias, null);
Certificate[] chain = ks.getCertificateChain(alias);
//OcspClient ocspClient = new OcspClientBouncyCastle();
TSAClient tsaClient = null;
for (int i = 0; i < chain.length; i++) {
X509Certificate cert = (X509Certificate)chain[i];
String tsaUrl = CertificateUtil.getTSAURL(cert);
if (tsaUrl != null) {
tsaClient = new TSAClientBouncyCastle(tsaUrl);
break;
}
}
List<CrlClient> crlList = new ArrayList<CrlClient>();
crlList.add(new CrlClientOnline(chain));
SC app = new SC();
app.sign(SRC, DEST, chain, pk, DigestAlgorithms.SHA256, providerMSCAPI.getName(), CryptoStandard.CMS, "Test", "London",
null, null, tsaClient, 0);
}
}
I get a little confused with this external signing process. I have my card reader installed, my card inserted, as I see it I am using Windows-MY key store..so i can call out certificates on the card from that key store as long as the card is inserted. When I check the certs via internet explorer I can see my certs that I got for free from internet and the ones that are on the card. I can't export the ones from the smart card with a private key, I know that is the whole point of the smart card so the process would be done externally.
My problem lies in that that with the code I wrote I get the document signed with a cert that I have already made and not with the ones from the card, how do I sign it with a cert from the card, one more thing is that I am never asked for my smart card PIN number.
Can anyone help me out, I am trying really hard to tackle this digital signature thing, I know that the next thing is doing it with PKCS11 and dll file but I am not there yet.Thanks
added:
Thanks for the answer Robert. You were right. I enumerated the alises in WINDOWS-MY keystore and I did in fact sign the document with the first alias that was listed and it was my non-smartcard cert/key pair. Obviously that is not what i want to do, how would I go about signing it with different cert/key, in my case with one that belongs to a smart card. Thanks again