加密/解密方法
https://wiki.openssl.org/index.php/EVP_Symmetric_Encryption_and_Decryption
int encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key,
unsigned char *iv, unsigned char *ciphertext)
{
EVP_CIPHER_CTX *ctx;
int len;
int ciphertext_len;
/* Create and initialise the context */
if (!(ctx = EVP_CIPHER_CTX_new())) handleErrors();
/* Initialise the encryption operation. IMPORTANT - ensure you use a key
* and IV size appropriate for your cipher
* In this example we are using 256 bit AES (i.e. a 256 bit key). The
* IV size for *most* modes is the same as the block size. For AES this
* is 128 bits */
if (1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv))
handleErrors();
/* Provide the message to be encrypted, and obtain the encrypted output.
* EVP_EncryptUpdate can be called multiple times if necessary
*/
if (1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len))
handleErrors();
ciphertext_len = len;
/* Finalise the encryption. Further ciphertext bytes may be written at
* this stage.
*/
if (1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len)) handleErrors();
ciphertext_len += len;
/* Clean up */
EVP_CIPHER_CTX_free(ctx);
return ciphertext_len;
}
int decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key,
unsigned char *iv, unsigned char *plaintext)
{
EVP_CIPHER_CTX *ctx;
int len;
int plaintext_len;
/* Create and initialise the context */
if (!(ctx = EVP_CIPHER_CTX_new())) handleErrors();
/* Initialise the decryption operation. IMPORTANT - ensure you use a key
* and IV size appropriate for your cipher
* In this example we are using 256 bit AES (i.e. a 256 bit key). The
* IV size for *most* modes is the same as the block size. For AES this
* is 128 bits */
if (1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv))
handleErrors();
/* Provide the message to be decrypted, and obtain the plaintext output.
* EVP_DecryptUpdate can be called multiple times if necessary
*/
if (1 != EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len))
handleErrors();
plaintext_len = len;
/* Finalise the decryption. Further plaintext bytes may be written at
* this stage.
*/
if (1 != EVP_DecryptFinal_ex(ctx, plaintext + len, &len)) handleErrors();
plaintext_len += len;
/* Clean up */
EVP_CIPHER_CTX_free(ctx);
return plaintext_len;
}
由于要使用BSTR类型,因此计划在ATL DLL中使用。
方法:
BSTR ENCRYPT(BSTR in, BSTR key) {
unsigned char * pBuffer = bstr_char(in);
unsigned char * key_v = bstr_char(key);
unsigned char *key_ = (unsigned char*)"857759686370038057";
char *temp = (char *)malloc(strlen((char*)key_v) + strlen((char*)key_) + 1);
strcpy(temp, (char*)key_);
strcat(temp, (char*)key_v);
unsigned char *iv = (unsigned char*)"2371904392800624";//(unsigned char*)"199618872547325";
unsigned char ciphertext[5000];
int ciphertext_len;
ciphertext_len = encrypt(pBuffer, strlen((char *)pBuffer), (unsigned char*)temp, iv, ciphertext);
ciphertext[ciphertext_len] = '\0';
std::string encoded = base64_encode(ciphertext, strlen((char *)ciphertext));
ULONG ulSize = strlen((char*)reinterpret_cast<const unsigned char*>(encoded.c_str())) + sizeof(char);
char* pszReturn = NULL;
pszReturn = (char*)::CoTaskMemAlloc(ulSize);
strcpy(pszReturn, (char*)(char*)reinterpret_cast<const unsigned char*>(encoded.c_str()));
BSTR out = SysAllocString(CA2W(pszReturn));
pBuffer = NULL;
key_v = NULL;
key_ = NULL;
temp = NULL;
iv = NULL;
return out;
}
BSTR DECRYPT(BSTR in, BSTR key) {
unsigned char * pBuffer = bstr_char(in);
unsigned char * key_v = bstr_char(key);
unsigned char *key_ = (unsigned char*)"857759686370038057";
char *temp = (char *)malloc(strlen((char*)key_v) + strlen((char*)key_) + 1);
strcpy(temp, (char*)key_);
strcat(temp, (char*)key_v);
unsigned char *iv = (unsigned char*)"2371904392800624";// (unsigned char*)"199618872547325";;
unsigned char decryptedtext[5000];
int decryptedtext_len;
std::string sName(reinterpret_cast<char*>(pBuffer));
std::string decoded = base64_decode(sName);
/* _DECRYPT_AES_ the ciphertext */
decryptedtext_len = decrypt((unsigned char*)reinterpret_cast<const unsigned char*>(decoded.c_str()),
strlen((char *)(char*)reinterpret_cast<const unsigned char*>(decoded.c_str())), (unsigned char*)temp, iv,
decryptedtext);
/* Add a NULL terminator. We are expecting printable text */
decryptedtext[decryptedtext_len] = '\0';
ULONG ulSize = strlen((char*)decryptedtext) + sizeof(char);
char* pszReturn = NULL;
pszReturn = (char*)::CoTaskMemAlloc(ulSize);
strcpy(pszReturn, (char*)decryptedtext);
BSTR out = SysAllocString(CA2W(pszReturn));
pBuffer = NULL;
key_v = NULL;
key_ = NULL;
temp = NULL;
iv = NULL;
return out;
}
Преобразованиетипов
unsigned char* bstr_char(BSTR in) {
int bstrLen = SysStringLen(in) + 1;
int len = WideCharToMultiByte(CP_ACP, 0, in, bstrLen, NULL, 0,
NULL, NULL);
unsigned char * pBuffer = new unsigned char[len];
WideCharToMultiByte(CP_ACP, 0, in, bstrLen, LPSTR(pBuffer), len,
NULL, NULL);
return pBuffer;
}
主要:
void main()
{
for (int i = 0; i < 100; i++) {
BSTR KEY = GET_PARAM_();
BSTR ENCR = ENCRYPT(SysAllocString(L"new string"), KEY);
BSTR decr = DECRYPT(ENCR, KEY);
wcout << ENCR << endl;
wcout << decr << endl;
cout << "----------------------------------" << endl;
}
system("pause");
}