数字签名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

回到顶部