其实OPENSSL真够强大的,很多加密算法,先看效果
本篇实现了AES加解密,并BASE64编码和反编码代码如下:
int CCode::SktEncData(const char *pstSData, int iSDataLen, char *pstBuffer, int iBufLen, const char *pstKey, int &iEncDataLen)
{
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
if (NULL == ctx)
{
return -2;
}
int iOutBufLen = -1;
unsigned char szOutBuf[SKT_MAX_ENC_DATA_LEN] = { 0 };
EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, (const unsigned char *)pstKey, NULL);
if (!EVP_EncryptUpdate(ctx, szOutBuf, &iOutBufLen, (const unsigned char *)pstSData, iSDataLen))
{
EVP_CIPHER_CTX_cleanup(ctx);
EVP_CIPHER_CTX_free(ctx);
return -3;
}
int iTempLen = -1;
if (!EVP_EncryptFinal_ex(ctx, szOutBuf + iOutBufLen, &iTempLen))
{
EVP_CIPHER_CTX_cleanup(ctx);
EVP_CIPHER_CTX_free(ctx);
return -4;
}
iOutBufLen += iTempLen;
iEncDataLen = iOutBufLen;
memcpy_s(pstBuffer, iBufLen, szOutBuf, iOutBufLen);
EVP_CIPHER_CTX_cleanup(ctx);
EVP_CIPHER_CTX_free(ctx);
return 0;
}
int CCode::SktDecData(const char *pstSData, int iSDataLen, char *pstBuffer, int iBufLen, const char *pstKey)
{
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
if (NULL == ctx)
{
return -1;
}
int iOutBufLen = -1;
unsigned char szOutBuf[SKT_MAX_ENC_DATA_LEN] = { 0 };
EVP_DecryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, (const unsigned char *)pstKey, NULL);
if (!EVP_DecryptUpdate(ctx, szOutBuf, &iOutBufLen, (const unsigned char *)pstSData, iSDataLen))
{
EVP_CIPHER_CTX_cleanup(ctx);
EVP_CIPHER_CTX_free(ctx);
return -2;
}
int iTempLen = -1;
EVP_DecryptFinal_ex(ctx, szOutBuf + iOutBufLen, &iTempLen);
iOutBufLen += iTempLen;
memcpy_s(pstBuffer, iBufLen, szOutBuf, iOutBufLen);
EVP_CIPHER_CTX_cleanup(ctx);
EVP_CIPHER_CTX_free(ctx);
return 0;
}int CCode::base64_encode(const char *s, char *d, int iDataLen)
{
int iRet = 0;
iRet = EVP_EncodeBlock((unsigned char *)d, (const unsigned char *)s, iDataLen);
if (0 >= iRet)
{
return -1;
}
return iRet;
}
int CCode::base64_decode(const char *s, char *d, int iDataLen)
{
int iRet = 0;
iRet = EVP_DecodeBlock((unsigned char *)d, (const unsigned char *)s, iDataLen);
if (0 >= iRet)
{
return -1;
}
return iRet;
}
并且用RSA生成了公私钥对,已封装代码实现RSA的公钥加密和私钥解密,代码如下:
int CCode::SktGetKey(int iKeyLen, const char *pstSeed, const char *pstSavePubKeyPath, const char *pstSavePriKeyPath, const char *pstPasswd, int iPasswdLen)
{
RSA *rsa = NULL;
RAND_seed(pstSeed, sizeof(pstSeed));
rsa = RSA_generate_key(iKeyLen, RSA_F4, NULL, NULL);
if (rsa == NULL)
{
return -1;
}
// 开始生成公钥文件
BIO *bp = BIO_new(BIO_s_file());
if (NULL == bp)
{
return -2;
}
if (BIO_write_filename(bp, (void *)pstSavePubKeyPath) <= 0)
{
return -3;
}
if (PEM_write_bio_RSAPublicKey(bp, rsa) != 1)
{
return -4;
}
BIO_free_all(bp);
// 生成私钥文件
bp = BIO_new_file(pstSavePriKeyPath, "w+");
if (NULL == bp)
{
return -5;
}
if (PEM_write_bio_RSAPrivateKey(bp, rsa, EVP_des_ede3_ofb(), (unsigned char *)pstPasswd, iPasswdLen, NULL, NULL) != 1)
{
return -6;
}
BIO_free_all(bp);
RSA_free(rsa);
return 0;
}
EVP_PKEY *CCode::SktOpenPublicKey(const char *pstKeyPath)
{
EVP_PKEY* key = NULL;
RSA *rsa = NULL;
OpenSSL_add_all_algorithms();
BIO *bp = BIO_new(BIO_s_file());;
BIO_read_filename(bp, pstKeyPath);
if (NULL == bp)
{
return NULL;
}
rsa = PEM_read_bio_RSAPublicKey(bp, NULL, NULL, NULL);
if (rsa == NULL)
{
BIO_free(bp);
RSA_free(rsa);
return NULL;
}
key = EVP_PKEY_new();
if (NULL == key)
{
RSA_free(rsa);
return NULL;
}
EVP_PKEY_assign_RSA(key, rsa);
BIO_free(bp);
// RSA_free(rsa);
return key;
}
EVP_PKEY *CCode::SktOpenPrivateKey(const char *pstKeyPath, const char *pstPasswd)
{
EVP_PKEY* key = NULL;
RSA *rsa = RSA_new();
OpenSSL_add_all_algorithms();
BIO *bp = NULL;
bp = BIO_new_file(pstKeyPath, "rb");
if (NULL == bp)
{
return NULL;
}
rsa = PEM_read_bio_RSAPrivateKey(bp, &rsa, NULL, (void *)pstPasswd);
if (rsa == NULL)
{
BIO_free(bp);
RSA_free(rsa);
return NULL;
}
key = EVP_PKEY_new();
if (NULL == key)
{
RSA_free(rsa);
return NULL;
}
EVP_PKEY_assign_RSA(key, rsa);
BIO_free(bp);
return key;
}
int CCode::SktPubEnc(const char *pstPubKeyPath, const char *pstSource, int iSLen, char *pstDest, size_t &destLen)
{
EVP_PKEY *pKey = SktOpenPublicKey(pstPubKeyPath);
if (NULL == pKey)
{
return -1;
}
EVP_PKEY_CTX *ctx = NULL;
OpenSSL_add_all_ciphers();
ctx = EVP_PKEY_CTX_new(pKey, NULL);
if (NULL == ctx)
{
EVP_PKEY_free(pKey);
return -2;
}
if (EVP_PKEY_encrypt_init(ctx) <= 0)
{
EVP_PKEY_free(pKey);
return -3;
}
if (EVP_PKEY_encrypt(ctx, (unsigned char *)pstDest, &destLen, (const unsigned char *)pstSource, iSLen) <= 0)
{
EVP_PKEY_CTX_free(ctx);
EVP_PKEY_free(pKey);
return -4;
}
EVP_PKEY_CTX_free(ctx);
EVP_PKEY_free(pKey);
return 0;
}
int CCode::SktPriDec(const char *pstPriKeyPath, const char *pstSource, int iSLen, char *pstDest, size_t &destLen, const char *pstPasswd)
{
EVP_PKEY *pKey = SktOpenPrivateKey(pstPriKeyPath, pstPasswd);
if (NULL == pKey)
{
return -1;
}
EVP_PKEY_CTX *ctx = NULL;
OpenSSL_add_all_ciphers();
ctx = EVP_PKEY_CTX_new(pKey, NULL);
if (NULL == ctx)
{
EVP_PKEY_free(pKey);
return -2;
}
if (EVP_PKEY_decrypt_init(ctx) <= 0)
{
EVP_PKEY_free(pKey);
return -3;
}
if (EVP_PKEY_decrypt(ctx, (unsigned char *)pstDest, &destLen, (const unsigned char *)pstSource, iSLen) <= 0)
{
EVP_PKEY_CTX_free(ctx);
EVP_PKEY_free(pKey);
return -4;
}
EVP_PKEY_CTX_free(ctx);
EVP_PKEY_free(pKey);
return 0;
}
源码工程下载地址: