1、java和cryptapi的配合
用java和cryptapi配合来加解密,要注意一个问题,java的数据都是大端的,big-endian,cryptapi的数据都是小端的,little-endian,所以互通的时候要做一下转换。
2、公钥的编码
// 公钥的Encode
BOOL EncodeRsaPubKey( unsigned long ulBitLen, unsigned char *pPubKeyDer, DWORD dwPubExponent,
unsigned char *pEncodedRsaPubKey, unsigned long *pulEncodedRsaPubKey )
{
// 公钥的封装PKCS1
BOOL ret = FALSE;
CRYPT_INTEGER_BLOB pPubKeyModuleBlob;
BYTE *pbEncodedModule = 0;
DWORD cbEncodedModule = NULL;
pPubKeyModuleBlob.cbData = ulBitLen / 8;
pPubKeyModuleBlob.pbData = pPubKeyDer;
// 公钥的Module的编码
ret = CryptEncodeObject( X509_ASN_ENCODING, X509_MULTI_BYTE_UINT, &pPubKeyModuleBlob, NULL, &cbEncodedModule );
if (!ret)
{
int err = GetLastError();
return FALSE;
}
pbEncodedModule = (unsigned char *)malloc( (cbEncodedModule + 1) * sizeof(unsigned char) );
if (NULL == pbEncodedModule)
{
return FALSE;
}
ret = CryptEncodeObject( X509_ASN_ENCODING, X509_MULTI_BYTE_UINT, &pPubKeyModuleBlob, pbEncodedModule, &cbEncodedModule );
if (!ret)
{
int err = GetLastError();
return FALSE;
}
// 公钥的Exponent的编码
BYTE *pbEncodedExponent = 0;
DWORD cbEncodedExponent = NULL;
ret = CryptEncodeObject( X509_ASN_ENCODING, X509_INTEGER, &dwPubExponent, NULL, &cbEncodedExponent );
if (!ret)
{
int err = GetLastError();
return FALSE;
}
pbEncodedExponent = (unsigned char *)malloc( (cbEncodedExponent + 1) * sizeof(unsigned char) );
if (NULL == pbEncodedExponent)
{
return FALSE;
}
ret = CryptEncodeObject( X509_ASN_ENCODING, X509_INTEGER, &dwPubExponent, pbEncodedExponent, &cbEncodedExponent );
if (!ret)
{
int err = GetLastError();
return FALSE;
}
// 公钥的编码
CRYPT_SEQUENCE_OF_ANY sequencePubKey;
sequencePubKey.cValue = 2;
sequencePubKey.rgValue = (PCRYPT_DER_BLOB)malloc( 2 * sizeof(CRYPT_DER_BLOB) );
if (NULL == sequencePubKey.rgValue)
{
return NULL;
}
sequencePubKey.rgValue[0].cbData = cbEncodedModule;
sequencePubKey.rgValue[0].pbData = pbEncodedModule;
sequencePubKey.rgValue[1].cbData = cbEncodedExponent;
sequencePubKey.rgValue[1].pbData = pbEncodedExponent;
DWORD cbEncodedPubKey = 0;
unsigned char *pbEncodedPubKey = NULL;
ret = CryptEncodeObject( X509_ASN_ENCODING, X509_SEQUENCE_OF_ANY, &sequencePubKey, NULL, &cbEncodedPubKey );
if (!ret)
{
return FALSE;
}
if (NULL == pEncodedRsaPubKey)
{
*pulEncodedRsaPubKey = cbEncodedPubKey;
return TRUE;
}
else if (*pulEncodedRsaPubKey < cbEncodedPubKey)
{
*pulEncodedRsaPubKey = cbEncodedPubKey;
return FALSE;
}
ret = CryptEncodeObject( X509_ASN_ENCODING, X509_SEQUENCE_OF_ANY, &sequencePubKey, pEncodedRsaPubKey, &cbEncodedPubKey );
if (!ret)
{
return FALSE;
}
*pulEncodedRsaPubKey = cbEncodedPubKey;
return TRUE;
}
3、公钥的编码-调用cryptapi函数
DWORD cbPubEncoded = 0;
BYTE *pbPubEecoded = NULL;
if(fResult)
{
fResult = CryptEncodeObjectEx(
X509_ASN_ENCODING,
RSA_CSP_PUBLICKEYBLOB,
pbKeyBlob,
CRYPT_ENCODE_ALLOC_FLAG,
NULL,
&pbDecoded,
&cbDecoded
);
}
if(pbDecoded)
LocalFree(pbDecoded);