I create a certificate with keytool:
keytool -genkeypair -alias sara -keyalg RSA -keysize 2048 -keypass
password -keystore "\Sviluppo\JavaKeyStore\keystore.jks" -storepass
12345678 -validity 360 -dname "cn=Sara, ou=***, o=***, l=Padova,
s=Italia, c=IT"
Then i want to sign a pdf with this certificate, i use Itextpdf to sign a pdf.
First I load private key and certificate from keystore:
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
File fileKeyStore = new File(pathKeyStore);
FileInputStream fis = new FileInputStream(fileKeyStore);
keyStore.load(fis, "12345678".toCharArray());
final PrivateKey privateKey = (PrivateKey) keyStore.getKey("sara", "password".toCharArray());
final Certificate certificate = keyStore.getCertificate(certID);
then I open document for calculate hash to sign:
PdfReader reader = new PdfReader(new RandomAccessFileOrArray(pdfInputPath), null);
OutputStream pdfOutputStream = new FileOutputStream(pdfOutputPath);
PdfStamper stp = PdfStamper.createSignature(reader, pdfOutputStream, '\0', tempPathFile, true)
PdfSignatureAppearance sap = stp.getSignatureAppearance();
PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED);
dic.setDate(dateNow);
sap.setCryptoDictionary(dic);
sap.setCrypto(privateKey, keyStore.getCertificateChain("sara"), null, PdfSignatureAppearance.SELF_SIGNED);
HashMap<PdfName, Integer> exc = new HashMap<PdfName, Integer>();
exc.put(PdfName.CONTENTS, (int) (6144 * 2 + 2));
sap.preClose(exc);
then calculate hash of sap.getRangeStream(), load certificate from keystore:
BufferedInputStream bis = new BufferedInputStream(sap.getRangeStream());
MessageDigest digest = MessageDigest.getInstance("SHA-256");
DigestInputStream dis = new DigestInputStream(bis, digest);
byte[] buff = new byte[512];
while (dis.read(buff) != -1) {
;
}
dis.close();
dis = null;
byte[] hashToSign= digest.digest();
bis.close();
I sign with certificate from keystore:
java.security.Signature signature = Signature.getInstance("SHA256withRSA");
signature.initSign(privateKey);
signature.update(hashToSign);
byte[] hashSigned = signature.sign();
at the end close pdf:
byte[] paddedSig = new byte[6144];
System.arraycopy(hashSigned, 0, paddedSig, 0, hashSigned.length);
PdfDictionary pdfDictionary = new PdfDictionary();
pdfDictionary.put(PdfName.CONTENTS, new PdfString(paddedSig).setHexWriting(true));
sap.close(pdfDictionary);
But the pdf signed is invalid: "There are errors in the formatting or information contained in this signature"
What's the problem, the certificare or signature?
Thanks for help
Sara
The cause for the "There are errors in the formatting or information contained in this signature" validation failure message is that your code puts a naked PKCS1 signature value where a full-fledged CMS signature container is expected:
You on the one hand use SELF_SIGNED in your sap.setCrypto which indicates that you want to create an adbe.x509.rsa_sha1 SubFilter signature, and on the other hand set the SubFilter to adbe.pkcs7.detached in your PdfSignature constructor.
This does not match at all, adbe.x509.rsa_sha1 uses naked PKCS1 signature values while adbe.pkcs7.detached uses CMS signature containers.
This should answer your question "What's the problem, the certificare or signature?"...
According to a comment you meanwhile found a solution in a copy of iText in Action, 2nd Edition.
Please be aware, though, that the iText signing API meanwhile has been substantially extended. If you are working with iText 5.5.x, you should download and read Digital Signatures for PDF Documents, a white paper by Bruno Lowagie (iText Software).
While the code from iText in Action, 2nd Edition, still focused on signatures according to ISO 32000-1:2008 (SOTA at the time of its publishing but not anymore), Digital Signatures for PDF Documents focuses on signatures according to PAdES which meanwhile have been included in ISO 32000-2:2017.
Related
I need to generate a CMS with SHA1+RSA detached signature in PEM format over a xml file input. I need to make this from Java code in runtime. I need to avoid the use of an external tool like OpenSSL. This is because we need invoke some services with the generated signature from Java and manage error properly if an exception ocurred in the signature process (the input xml changes every day).
The file I have to sign looks like this:
<header>
<generationTime>2017-04-17T00:00:01-03:00</generationTime>
<expirationTime>2017-04-17T23:59:59-03:00</expirationTime>
</header>
Using OpenSSL, with a private key and a certificate, the signature is generated executing this command:
openssl cms -sign -in tra.xml -inkey MyPrivateKey -signer myCertificate.pem -out tra.xml.cms -outform PEM -nodetach
The generated PEM signature in that case is:
-----BEGIN CMS-----
MIIGdAYJKoZIhvcNAQcCoIIGZTCCBmECAQExDTALBglghkgBZQMEAgEwgaIGCSqG
SIb3DQEHAaCBlASBkTxoZWFkZXI+ICAgIA0KPGdlbmVyYXRpb25UaW1lPjIwMTct
MDQtMTdUMDA6MDA6MDEtMDM6MDA8L2dlbmVyYXRpb25UaW1lPg0KPGV4cGlyYXRp
b25UaW1lPjIwMTctMDQtMTdUMjM6NTk6NTktMDM6MDA8L2V4cGlyYXRpb25UaW1l
Pg0KPC9oZWFkZXI+DQqgggNOMIIDSjCCAjKgAwIBAgIII0Or3JGYSY4wDQYJKoZI
hvcNAQENBQAwODEaMBgGA1UEAwwRQ29tcHV0YWRvcmVzIFRlc3QxDTALBgNVBAoM
BEFGSVAxCzAJBgNVBAYTAkFSMB4XDTE3MDEyNjE2MDIwNFoXDTE5MDEyNjE2MDIw
NFowMDETMBEGA1UEAwwKYWNjZXNvQUZJUDEZMBcGA1UEBRMQQ1VJVCAyMDI5OTUw
Mzk2OTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPhtRXT8FQPvcFvQ
CUSZaHTtcc864DsvP3zedpcr1gDLyJRMMlKnV0mZVJXEeC6eo6AV71kv2QpFUUp3
OGUAS/zJGXByCJ2trV/pXrvppmJvAJARlfw6KoqQBY+YYoIinIzCbUHdvoPwub2K
o7081VlmLxUffiDElbAi3gi41z/W6pD57i3U1uPjS45HRvIn7Vcv4epcH3x9+IDC
DEbZ0hsKIiuJrH4RO1k50gSSaXjvAQSG8kbEXMQ89AxAeynI8jk964JpHc0qLj6y
1sfvAyCSPq8ZFURribdboZi8G6oAccIM1pyMKA13+AcPkOFy0SyotjnFgrK2MMVZ
+vEgNwECAwEAAaNgMF4wDAYDVR0TAQH/BAIwADAfBgNVHSMEGDAWgBSzstP//em6
3t6NrxEhnNYgffJPbzAdBgNVHQ4EFgQUEuAlczdaDyI7hGuwyqR6ipLvTikwDgYD
VR0PAQH/BAQDAgXgMA0GCSqGSIb3DQEBDQUAA4IBAQA+Pg0RQ7J5qiViZMk94tgD
WAgTT0iIoVm65Xn2/czlBgefhxY6l4SKqQCONJpAMCUI2mEG6qgOg/u+GbN3pR+p
1FSC2yDETRIpf9nekooTEot6A9r2Huykd4Sp3QHZEly9Sx3+3ek+w7Mg0k/+AtgT
JodP0ArzCQyvBJCR8ZTTHjUazf2/9o0iEqQIKyp1vn2vv3JlMONBb7+ALqzCXgCb
FVjFpF8PpZyWM/+J6WVrU19hB3wsdyhLh0M5CiBQ19aGC8R/0bWm2w2P3awOn8r4
r/duYqdGzK/7zTpjtvk0VKax6/Pe5WIFLKXTP9LGpxbCQjxKpbVxMbzx1pDPGBjF
MYICVDCCAlACAQEwRDA4MRowGAYDVQQDDBFDb21wdXRhZG9yZXMgVGVzdDENMAsG
A1UECgwEQUZJUDELMAkGA1UEBhMCQVICCCNDq9yRmEmOMAsGCWCGSAFlAwQCAaCB
5DAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0xNzA0
MTcxMzM3MDVaMC8GCSqGSIb3DQEJBDEiBCBL5i3jl4+rfSfo/Pcu/CbI6JHGj0jg
UGI/EucH7LBM6jB5BgkqhkiG9w0BCQ8xbDBqMAsGCWCGSAFlAwQBKjALBglghkgB
ZQMEARYwCwYJYIZIAWUDBAECMAoGCCqGSIb3DQMHMA4GCCqGSIb3DQMCAgIAgDAN
BggqhkiG9w0DAgIBQDAHBgUrDgMCBzANBggqhkiG9w0DAgIBKDANBgkqhkiG9w0B
AQEFAASCAQAMNHskWrhZCu/DmFQLCrAweTEacCwTJdYOx+704PS6DkflXQLpD9q4
B0Psxx6gmN7HkHkrY4bD250TefZpKyD7IfJjdNQEz4SzgmtgMTl2a0JvlgpWSNjq
au0WMkFXnoSo0oJ3s4FSHWAe15DlNFQn9HbKfjI/sIHpkhgA0u/Kr6ZHUSIEnfxS
KVNxQ224uvFPGCggHnPIdtBRFgGn44J1hRyiYm0BLqJO5sAwV23gWB8OztsuBHqj
imi4WWXnCVPk7/6BMGNuLpUH3bH6nfIPDfSL7bb7vXRhcQrjTU8o38/C3gDsJr2A
4JNHkIjPMoo4l+wlS66MJQpOXadjYaFi
-----END CMS-----
Thats is what I need generate over Java 7.
I already read and make many test with Bouncy Castle and java.security.cert standard API, but I can't generate the same signature result. I checked internal representation from Bouncy Castle and the API is using DER format to hold the signature. And in the examples are always showing how to verify a signature, but no how to generate one and save it in a file or print it in PEM form.
Here is an example of how I generate a BC signature, but the result is pretty different from what I need:
public static String encryptSHA1RSA(String xmlPayload) throws Exception {
List certList = new ArrayList();
CMSTypedData msg = new CMSProcessableByteArray(xmlPayload.getBytes());
certList.add(CMSEncryptor.getSingCert());
Store certs = new JcaCertStore(certList);
CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(CMSEncryptor.getPrivateKey());
gen.addSignerInfoGenerator( new JcaSignerInfoGeneratorBuilder(
new JcaDigestCalculatorProviderBuilder().setProvider("BC").build())
.build(sha1Signer, CMSEncryptor.getSingCert()));
gen.addCertificates(certs);
CMSSignedData sigData = gen.generate(msg, true);
ASN1InputStream asn1 = new ASN1InputStream(sigData.getEncoded());
FileOutputStream fos = new FileOutputStream(getSecurityFolderPath() + "/tra.test.cms");
DEROutputStream dos = new DEROutputStream(fos);
dos.writeObject(asn1.readObject());
dos.flush();
dos.close();
asn1.close();
return Base64Util.encodeBase64(new String(sigData.getEncoded()));
}
Is different also if I encode the result with base64:
return Base64Util.encodeBase64(new String(sigData.getEncoded()));
Any tips will be very apreciated
I've made a test using BouncyCastle (bcprov-jdk15on) 1.56 and Java 1.7
To convert your signature to PEM format, you can use BouncyCastle's JcaPEMWriter (or just PEMWriter for older versions), like this:
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.cms.ContentInfo;
import org.bouncycastle.openssl.jcajce.JcaPEMWriter;
// ... used the same code you posted above ...
// *** NOTE: if you want a detached signature, change the second parameter to false ***
CMSSignedData sigData = gen.generate(msg, false);
// write sigData to output.pem file, using a pem writer
ContentInfo ci = ContentInfo.getInstance(ASN1Sequence.fromByteArray(sigData.getEncoded()));
JcaPEMWriter writer = new JcaPEMWriter(new FileWriter("output.pem"));
writer.writeObject(ci);
writer.close();
The result is slightly different, because BouncyCastle generates a file with BEGIN PKCS7 and END PKCS7 headers (instead of BEGIN CMS and END CMS):
-----BEGIN PKCS7-----
MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAaCA
JIAEgYg8aGVhZGVyPgo8Z2VuZXJhdGlvblRpbWU+MjAxNy0wNC0xN1QwMDowMDow
... lots of base64 lines ...
WHkpUQDxQj+v/SbMGa5+U7VC8+HNOfgFOba+U56QLhbhDEeaaozwATXveRkqhsdn
AAAAAAAA
-----END PKCS7-----
But the output file is a valid digital signature anyway. And both (PKCS7 and CMS headers) can be read by OpenSSL and BouncyCastle. So, unless you need exactly BEGIN CMS header, I believe this will be enough.
If you don't want to write to a file and get a String instead, you can use java.io.StringWriter combined with JcaPEMWriter:
StringWriter sw = new StringWriter();
JcaPEMWriter writer = new JcaPEMWriter(sw);
writer.writeObject(ci);
writer.close();
String pemString = sw.toString(); // pemString will be the PEM formatted string (with BEGIN PKCS7 header)
Please, could someone point me in the right direction to digitally sign an MS-Office document (docx, xlsx, pptx) in Apache POI, or any other open source library?
I have already reviewed the classes under org.apache.poi.openxml4j.opc.signature but I cannot understand how I could add a signature to a document.
Check this sample code .. this sample code uses a file keystore PFX (PKCS12) .. Signs the Document and verify it.
// loading the keystore - pkcs12 is used here, but of course jks & co are also valid
// the keystore needs to contain a private key and it's certificate having a
// 'digitalSignature' key usage
char password[] = "test".toCharArray();
File file = new File("test.pfx");
KeyStore keystore = KeyStore.getInstance("PKCS12");
FileInputStream fis = new FileInputStream(file);
keystore.load(fis, password);
fis.close();
// extracting private key and certificate
String alias = "xyz"; // alias of the keystore entry
Key key = keystore.getKey(alias, password);
X509Certificate x509 = (X509Certificate)keystore.getCertificate(alias);
// filling the SignatureConfig entries (minimum fields, more options are available ...)
SignatureConfig signatureConfig = new SignatureConfig();
signatureConfig.setKey(keyPair.getPrivate());
signatureConfig.setSigningCertificateChain(Collections.singletonList(x509));
OPCPackage pkg = OPCPackage.open(..., PackageAccess.READ_WRITE);
signatureConfig.setOpcPackage(pkg);
// adding the signature document to the package
SignatureInfo si = new SignatureInfo();
si.setSignatureConfig(signatureConfig);
si.confirmSignature();
// optionally verify the generated signature
boolean b = si.verifySignature();
assert (b);
// write the changes back to disc
pkg.close();
Here's the sample source : https://poi.apache.org/apidocs/org/apache/poi/poifs/crypt/dsig/SignatureInfo.html
I hope this could help!
Using the following command ;
keytool -keystore org726.store -genkey -alias org726
The password i used for above steps was "password". Its hardcoded in the code underneath in ks.load().
i am generating the keystore and using a java program to digitally sign the pdf
public void signPdfFirstTime(String src, String dest)
{
try{
BouncyCastleProvider provider = new BouncyCastleProvider();
Security.addProvider(provider);
//KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
String path = properties.getProperty("PRIVATE");
String keystore_password = properties.getProperty("PASSWORD");
String PASSWORD = "password";
ks.load(new FileInputStream(KEYSTORE1), PASSWORD.toCharArray());
//ks.load(new FileInputStream(path), keystore_password.toCharArray());
String alias = (String)ks.aliases().nextElement();
PrivateKey pk = (PrivateKey) ks.getKey(alias, "password".toCharArray());
Certificate[] chain = ks.getCertificateChain(alias);
PdfReader reader = new PdfReader(src);
FileOutputStream os = new FileOutputStream(dest);
PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0');
// appearance
PdfSignatureAppearance appearance = stamper .getSignatureAppearance();
appearance.setImage(Image.getInstance("D:\\logo.jpg"));
appearance.setReason("I've written this.");
appearance.setLocation("Chennai");
appearance.setVisibleSignature(new Rectangle(72, 732, 144, 780), 1, "first");
// digital signature
System.out.println(PageSize.A4.getHeight());
System.out.println(PageSize.A4.getWidth());
ExternalSignature es = new PrivateKeySignature(pk, DigestAlgorithms.SHA1, provider.getName());
ExternalDigest digest = new BouncyCastleDigest();
MakeSignature.signDetached(appearance, digest, es, chain, null, null, null, 0, CryptoStandard.CADES);
}catch(Exception e)
{
e.printStackTrace();
}
}
But in the resultant pdf i am getting:
Signer's identity is unknown because it has not been included in the list of your trusted certificates.Its a .store file. Upon debugging in Eclipse its x509 cert upon inspection.
How do i include it in list of trusted certificates?
The Signer's identity is unknown because it has not been included in the list of your trusted certificates message is from adobe acrobat or from reader. To solve the problem you've to include the issuer CA of your certificate to acrobat configuration.
You can do the following next steps:
Validate the signature from acrobat and then when adobe says that is invalid access to the signature properties. On the new window select signer tab and click on show certificate button then you see the certificate validation path. Now you have to select the issuer CA certificate and in the trust tab click on Add to Trusted identities... button, then you can validate the signature again and this time must be valid.
If for test purpose you're signing with a selfsigned certificate add directly the certificate to trusted identities instead of the CA.
Hope this helps,
I am new to Cryptography and so please excuse me if you think this is a basic question
I have a .p7b file which I need to read and extract the individual public certificates i.e the .cer files and store it in the key store. I need not worry about persisting in the key store as there is already a service which takes in the .cer file as byte[] and saves that.
What i want to know is , how do i read the .p7b and extract the individual .cer file? I know that can be done via the openSSL commands, but i need to do the same in java. I need to also read the Issued By name as that will be used as a unique key to persist the certificate.
Thanks in advance
You can get the certificates from a PKCS#7 object with BouncyCastle. Here is a quick code sample:
public Collection<X59Certificate> getCertificates(String path) throws Exception
{
Security.addProvider(new BouncyCastleProvider());
CMSSignedData sd = new CMSSignedData(new FileInputStream(path));
X509Store store = sd.getCertificates("Collection", "BC");
Collection<X509Certificate> certificates = store.getMatches(X509CertStoreSelector.getInstance(new X509CertSelector()));
return certificates;
}
Note that a PKCS#7 may contain more than one certificate. Most of the time it includes intermediate certification authority certificates required to build the certificate chain between the end-user certificate and the root CA.
I was successfully able to read the individual .X509 certificates from the p7b files. Here are the steps
First step includes, getting a byte[] from the java.io.File. The steps include to remove the -----BEGIN PKCS7----- and -----END PKCS7----- from the file, and decode the remaining base64 encoded String.
BufferedReader reader = new BufferedReader(new FileReader(file));
StringBuilder cerfile = new StringBuilder();
String line = null;
while(( line = reader.readLine())!=null){
if(!line.contains("PKCS7")){
cerfile.append(line);
}
}
byte[] fileBytes = Base64.decode(cerfile.toString().getBytes());
The next step is to use the BouncyCastle api to parse the file
CMSSignedData dataParser = new CMSSignedData(trustBundleByte);
ContentInfo contentInfo = dataParser.getContentInfo();
SignedData signedData = SignedData.getInstance(contentInfo.getContent());
CMSSignedData encapInfoBundle = new CMSSignedData(new CMSProcessableByteArray(signedData.getEncapContentInfo().getContent().getDERObject().getEncoded()),contentInfo);
SignedData encapMetaData = SignedData.getInstance(encapInfoBundle.getContentInfo().getContent());
CMSProcessableByteArray cin = new CMSProcessableByteArray(((ASN1OctetString)encapMetaData.getEncapContentInfo().getContent()).getOctets());
CertificateFactory ucf = CertificateFactory.getInstance("X.509");
CMSSignedData unsignedParser = new CMSSignedData(cin.getInputStream());
ContentInfo unsginedEncapInfo = unsignedParser.getContentInfo();
SignedData metaData = SignedData.getInstance(unsginedEncapInfo.getContent());
Enumeration certificates = metaData.getCertificates().getObjects();
// Build certificate path
while (certificates.hasMoreElements()) {
DERObject certObj = (DERObject) certificates.nextElement();
InputStream bin = new ByteArrayInputStream(certObj.getDEREncoded());
X509Certificate cert = (X509Certificate) ucf.generateCertificate(bin);
X500Name x500name = new JcaX509CertificateHolder(cert).getSubject();
RDN cn = x500name.getRDNs(BCStyle.CN)[0];
}
The above steps are working fine, but i am sure there are other solutions with less lines of code to achieve this. I am using bcjdk16 jars.
I want to sign file with the SunMSCAPI provider. As public key and signatures needs to be imported using MS Crypto API.
Generally generating signatures with SHA1withRSA, ends up with big-endian to little-endian (byte order) conversion.
//generate keystore with java keytool
$Keytool -genkey -alias tsign -keystore c:\test\tsignjks.p12 - keyalg rsa -storetype pkcs12
In Java application:
//for signing and getting keystore, assuming windows certificate is installed
..ks = KeyStore.getInstance("Windows-MY","SunMSCAPI");
PrivateKey priv = ks.getKey("tsign",password);
Signature rsa = Signature.getInstance("SHA1withRSA","SunMSCAPI");
rsa.initSign(priv);
..
rsa.update(buffer, 0, len);
..
byte[] realSig = rsa.sign();
//for writing public key for ms crypto api or exporting it from windows certificate store
Certificate cert = ks.getCertificate("tsign");
byte[] encodedCert = cert.getEncoded();
FileOutputStream certfos = new FileOutputStream("tsigncer.cer");
certfos.write(encodedCert);
//for writing signatures for ms crypto api
FileOutputStream sigfos = new FileOutputStream(targetPath + "/"
+ signatureName);
sigfos.write(realSig);
I believe that SunMSCAPI can resolve my problem, but I don't know when i import public key using MS Crypto API, It never import at at first stage (unless i change big endian to little endian byte order) below is my code for crypto API.
LPCSTR file = "tsigncer.cer";
//LPCSTR file = "omsign.p12";
BOOL crypt_res = FALSE;
HCRYPTPROV crypt_prov_hndl = NULL;
crypt_res = CryptAcquireContext(&crypt_prov_hndl, NULL, NULL, PROV_RSA_FULL, 0/*CRYPT_NEWKEYSET*/);
//crypt_res = CryptAcquireContext(&crypt_prov_hndl, NULL, NULL, PROV_DSS, CRYPT_VERIFYCONTEXT/*CRYPT_NEWKEYSET*/);
if (!crypt_res) {
HRESULT decode_hr = __HRESULT_FROM_WIN32(GetLastError());
return decode_hr;
}
// Load key file
HANDLE fileHandle = CreateFile(file, // name of the write
GENERIC_READ, // open for writing
0, // do not share
NULL, // default security
OPEN_EXISTING, // create new file only
FILE_ATTRIBUTE_NORMAL, // normal file
NULL); // no attr. template
if (fileHandle == INVALID_HANDLE_VALUE)
{
DWORD d = GetLastError();
return -1;
}
BYTE buffer[2056];
DWORD fileSize = 0;
DWORD fileSizeResult = GetFileSize(fileHandle, &fileSize);
DWORD numBytesRead = 0;
BOOL fileLoadResult = ReadFile(fileHandle, (PVOID)buffer, fileSizeResult, &numBytesRead, NULL);
// Import key
BOOL result = ImportKey(crypt_prov_hndl, (LPBYTE)buffer, numBytesRead);
//result is always false..
If you work with MSCAPI, it is assumed that you've added your key to the Microsoft Certificate store. You can check if the key is present by going to "Internet Properties" > "Content" > "Certificates" which gives you a list of certificates that are available. If your certificate isn't there, you can't use it. If it's there, you need this code:
SunMSCAPI providerMSCAPI = new SunMSCAPI();
Security.addProvider(providerMSCAPI);
KeyStore ks = KeyStore.getInstance("Windows-MY");
ks.load(null, null);
From there on, the code is pretty standard. Please consult my book on digital signatures for more info (the book is free).
IMPORTANT ADDITION: I forgot to mention that SunMSCAPI isn't present in the 64-bit version of Java 6 (I don't know about Java 7). You can fix this by installing the 32-bit version.