Digitally Signed SunMSCAPI Provider and MS Crypto API

I want to sign a file using the SunMSCAPI provider. Since the public key and signatures must be imported using the MS Crypto API.

Typically, signature generation with SHA1withRSA ends with a conversion with a byte to a byte number with a by-endan.

 //generate keystore with java keytool $Keytool -genkey -alias tsign -keystore c:\test\tsignjks.p12 - keyalg rsa -storetype pkcs12 

In a 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 solve my problem, but I do not know when I import the public key using the MS Crypto API, it is never imported at the first stage (unless I change the byte order with bytes) this is my code for the cryptographic 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.. 
+4
source share
1 answer

If you are using MSCAPI, it is assumed that you have 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 available certificates. If your certificate is not there, you will not be able to use it. If it is there, you need this code:

 SunMSCAPI providerMSCAPI = new SunMSCAPI(); Security.addProvider(providerMSCAPI); KeyStore ks = KeyStore.getInstance("Windows-MY"); ks.load(null, null); 

From there, the code is pretty standard. Please refer to my book on digital signatures for more information (the book is free).

IMPORTANT ADDITION: I forgot to mention that SunMSCAPI is missing from the 64-bit version of Java 6 (I don't know about Java 7). You can fix this by installing the 32-bit version.

+5
source

All Articles