我试图在c ++编码中压缩字符串并存储在Linux服务器的MYSQL varchar字段中,然后获取字符串然后在.Net中解压缩。我已经尝试了很多方法,但没有运气。请帮帮我。
这是我的c ++代码。
#include <iostream>
#include <string>
#include <vector>
#include <stdlib.h>
#include <openssl/evp.h>
#include "zlib.h"
#include "base64.cpp"
using namespace std;
#define AES_BLOCK_SIZE 256
int aes_init(unsigned char *key_data, int key_data_len, unsigned char *salt, EVP_CIPHER_CTX *e_ctx,
EVP_CIPHER_CTX *d_ctx)
{
int i, nrounds = 5;
unsigned char key[32], iv[32];
/*
* Gen key & IV for AES 256 CBC mode. A SHA1 digest is used to hash the supplied key material.
* nrounds is the number of times the we hash the material. More rounds are more secure but
* slower.
*/
i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), salt, key_data, key_data_len, nrounds, key, iv);
if (i != 32) {
printf("Key size is %d bits - should be 256 bits\n", i);
return -1;
}
EVP_CIPHER_CTX_init(e_ctx);
EVP_EncryptInit_ex(e_ctx, EVP_aes_256_cbc(), NULL, key, iv);
EVP_CIPHER_CTX_init(d_ctx);
EVP_DecryptInit_ex(d_ctx, EVP_aes_256_cbc(), NULL, key, iv);
return 0;
}
unsigned char *aes_encrypt(EVP_CIPHER_CTX *e, unsigned char *plaintext, int *len)
{
/* max ciphertext len for a n bytes of plaintext is n + AES_BLOCK_SIZE -1 bytes */
int c_len = *len + AES_BLOCK_SIZE - 1, f_len = 0;
unsigned char *ciphertext = (unsigned char *)malloc(c_len);
/* allows reusing of 'e' for multiple encryption cycles */
if(!EVP_EncryptInit_ex(e, NULL, NULL, NULL, NULL)){
printf("ERROR in EVP_EncryptInit_ex \n");
return NULL;
}
/* update ciphertext, c_len is filled with the length of ciphertext generated,
*len is the size of plaintext in bytes */
if(!EVP_EncryptUpdate(e, ciphertext, &c_len, plaintext, *len)){
printf("ERROR in EVP_EncryptUpdate \n");
return NULL;
}
/* update ciphertext with the final remaining bytes */
if(!EVP_EncryptFinal_ex(e, ciphertext+c_len, &f_len)){
printf("ERROR in EVP_EncryptFinal_ex \n");
return NULL;
}
*len = c_len + f_len;
return ciphertext;
}
std::string string_compress(std::string const& s) {
unsigned int sourceSize = s.size();
const char * source = s.c_str();
unsigned long dsize = sourceSize + (sourceSize * 0.1f) + 16;
char * destination = new char[dsize];
int result = compress((unsigned char *)destination, &dsize, (const unsigned char *)source, sourceSize);
if(result != Z_OK)
std::cout << "Compress error occured! Error code: " << result << std::endl;
return destination;
}
int main (int argc, char * const argv[]) {
std::string to_compress = "1^52^1^52,2^57^52^109,3^6^109^115";
std::string compressed = string_compress(to_compress);
/* "opaque" encryption, decryption ctx structures that libcrypto uses to record
status of enc/dec operations */
EVP_CIPHER_CTX en, de;
/* The salt paramter is used as a salt in the derivation: it should point to an 8 byte buffer or NULL if no salt is used. */
unsigned char salt[] = {1,2,3,4,5,6,7,8};
unsigned char *key_data;
int key_data_len, i;
char *input;
input = new char[compressed.size()+1];
std::copy(compressed.begin(), compressed.end(), input);
/* the key_data is read from the argument list */
key_data = (unsigned char *)"X";
key_data_len = 1;
/* gen key and iv. init the cipher ctx object */
if (aes_init(key_data, key_data_len, salt, &en, &de)) {
printf("Couldn't initialize AES cipher\n");
return -1;
}
unsigned char *ciphertext;
int olen, len;
/* The enc/dec functions deal with binary data and not C strings. strlen() will
return length of the string without counting the '\0' string marker. We always
pass in the marker byte to the encrypt/decrypt functions so that after decryption
we end up with a legal C string */
olen = len = strlen(input)+1;
ciphertext = aes_encrypt(&en, (unsigned char *)input, &len);
std::string encodedData = base64_encode(ciphertext, len);
std::string query="update cac001_000001a set datap=" + TOSQL(encodedData) + " where category_id=1 and cache_key_id=1";
objcache.Save(query);
free(ciphertext);
EVP_CIPHER_CTX_cleanup(&de);
EVP_CIPHER_CTX_cleanup(&en);
return 0;
}
这是我的.Net代码
Public Sub Decompress()
Dim strComp As String
Dim strDecomp As String
Dim salt As Byte() = {1, 2, 3, 4, 5, 6, 7, 8}
Dim keyBytes As Byte() = New Byte() {243, 203, 30, 241, 23, 196, 12, 54, 35, 77, 92, 17, 170, 34, 235, 42, 75, 52, 118, 3, 64, 84, 203, 40, 1, 68, 83, 16, 206, 147, 126, 48}
Dim VectorBytes As Byte() = New Byte() {100, 56, 168, 166, 119, 82, 215, 80, 85, 81, 209, 120, 205, 124, 157, 172, 208, 252, 38, 89, 255, 127, 0, 0, 21, 71, 225, 196, 50, 0, 0, 0}
strComp = Decrypt(strComp, keyBytes, VectorBytes)
strDecomp = clsZlib.BytesToString(clsZlib.Decompress(clsZlib.StringToBytes(strComp)))
End Sub
Public Function Decrypt(ByVal Text As String, ByVal keyBytes As Byte(), ByVal VectorBytes As Byte()) As String
Try
Dim TextBytes As Byte() = Convert.FromBase64String(Text)
Dim rijKey As New RijndaelManaged()
rijKey.BlockSize = 256
'rijKey.IV = VectorBytes
rijKey.Mode = CipherMode.CBC
Dim decryptor As ICryptoTransform = rijKey.CreateDecryptor(keyBytes, VectorBytes)
Dim memoryStream As New MemoryStream(TextBytes)
Dim cryptoStream As New CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read)
Dim pTextBytes As Byte() = New Byte(TextBytes.Length - 1) {}
Dim decryptedByteCount As Integer '= cryptoStream.Read(pTextBytes, 0, pTextBytes.Length)
While ((decryptedByteCount = cryptoStream.Read(pTextBytes, 0, pTextBytes.Length)) > 0)
End While
memoryStream.Close()
cryptoStream.Close()
Dim plainText As String = Encoding.UTF8.GetString(pTextBytes, 0, decryptedByteCount)
Return plainText
Catch a As Exception
Response.Write("Falsches Passwort " + a.Message)
Dim t As String = ""
Return t
End Try
End Function
Public Class clsZlib
<DllImport("zlib.DLL", EntryPoint:="compress")> _
Private Shared Function ZCompress(ByVal dest As Byte(), ByRef destLen As Integer, ByVal src As Byte(), ByVal srcLen As Integer) As Integer
' Leave function empty - DLLImport attribute forwards calls to CompressByteArray to compress in zlib.dLL
End Function
<DllImport("zlib.DLL", EntryPoint:="uncompress")> _
Private Shared Function ZUncompress(ByVal dest As Byte(), ByRef destLen As Integer, ByVal src As Byte(), ByVal srcLen As Integer) As Integer
' Leave function empty - DLLImport attribute forwards calls to UnCompressByteArray to Uncompress in zlib.dLL
End Function
Public Shared Function BytesToString(ByVal bytes() As Byte) As String
Return Encoding.UTF8.GetString(bytes)
End Function
Public Shared Function BytesToString(ByVal bytes() As Byte, ByVal index As Integer, ByVal count As Integer) As String
If bytes.Length < count Then count = bytes.Length
Return Encoding.UTF8.GetString(bytes, index, count)
'Return Encoding.GetEncoding(1256).GetString(bytes, index, count)
End Function
Public Shared Function StringToBytes(ByVal s As String) As Byte()
Return Encoding.UTF8.GetBytes(s)
End Function
Public Shared Function Decompress(ByVal Data() As Byte) As Byte()
'DeCompresses Data into a temp buffer..note that Origsize must be the size of the original data before compression
'Returns compressed Data in Data if TempBuff not specified
'Returns Result = Size of decompressed data if ok, -1 if not
'Allocate memory for buffers
'If Data.Length < 23 Then Return Data
Try
Dim result As Integer
Dim Origsize As Short = (Data(0) * &H100 Or Data(1))
Dim TempBuffer(UBound(Data) - 3) As Byte
'Decompress data
Buffer.BlockCopy(Data, 2, TempBuffer, 0, UBound(Data) - 2)
ReDim Data(Origsize - 1)
result = ZUncompress(Data, Origsize, TempBuffer, UBound(TempBuffer) + 1)
TempBuffer = Nothing
Return Data
Catch ex As Exception
Return Data
End Try
End Function
End Class
请帮帮我。