数字签名SunMSCAPI提供程序和MS Crypto API
我想与SunMSCAPI
提供商签署文件。由于公共密钥和签名需要使用MS Crypto API导入。
通常,使用生成签名SHA1withRSA
最终以big-endian到little-endian(字节顺序)转换为结尾。
//generate keystore with java keytool$Keytool -genkey -alias tsign -keystore c:\test\tsignjks.p12 - keyalg rsa -storetype pkcs12
在Java应用程序中:
//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);
我相信SunMSCAPI
可以解决我的问题,但是我不知道何时使用MS Crypto
API导入公钥,它永远不会在第一阶段导入(除非我将大字节序更改为小字节序),这是我的加密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..
回答:
如果使用MSCAPI,则假定您已将密钥添加到Microsoft证书存储中。您可以通过转到“
Internet属性”>“内容”>“证书”来检查该密钥是否存在,该列表为您提供了可用证书的列表。如果您的证书不存在,则无法使用。如果存在,则需要以下代码:
SunMSCAPI providerMSCAPI = new SunMSCAPI();Security.addProvider(providerMSCAPI);
KeyStore ks = KeyStore.getInstance("Windows-MY");
ks.load(null, null);
从那里开始,代码是非常标准的。请查阅我的数字签名书以获取更多信息(该书是免费的)。
我忘了提到SunMSCAPI在64位版本的Java 6中不存在(我不了解Java 7)。您可以通过安装32位版本来解决此问题。
以上是 数字签名SunMSCAPI提供程序和MS Crypto API 的全部内容, 来源链接: utcz.com/qa/408255.html