JNI wrapper to openssl AES_ecb_encrypt not working - java-native-interface

I'm doing a JNI wrapper to call AES_ecb_encrypt function from openssl.
The wrapper looks like this:
#include "aes.h"
#include <jni.h>
#include <string.h>
jbyteArray
Java_com_package_AESDecryptionFilterInputStream_encrypt( JNIEnv* env,
jobject this,
jbyte* data,
jbyte* userkey,
jint length,
jint mode)
{
const unsigned char* indata = (unsigned char*)data;
const unsigned char* ukey = (unsigned char*)userkey;
unsigned char *outdata = NULL;
outdata = malloc(length);
AES_KEY key;
memset(&key, 0, sizeof(AES_KEY));
if(mode == AES_ENCRYPT)
AES_set_encrypt_key(ukey, 128, &key);
else
AES_set_decrypt_key(ukey, 128, &key);
AES_ecb_encrypt(indata, outdata, &key, mode);
jbyteArray bArray = (*env)->NewByteArray(env, length);
jboolean isCopy;
void *decrypteddata = (*env)->GetPrimitiveArrayCritical(env, (jarray)bArray, &isCopy);
memcpy(decrypteddata, outdata, length);
(*env)->ReleasePrimitiveArrayCritical(env, bArray, decrypteddata, 0);
return bArray;
}
but, when I call it from java code to encrypt and then decrypt a string, the results aren't correct.
I'm declaring the library like this:
static {
System.loadLibrary("aes_ecb");
}
public native byte[] encrypt(byte[] data, byte[] userkey, int length, int mode);
I'm calling it like this:
byte[] dec = "0123456789012345".getBytes();
byte[] enc = encrypt(dec, decryptionKey.getBytes(), dec.length, 1);
byte[] dec2 = encrypt(enc, decryptionKey.getBytes(), enc.length, 0);
The problem is that the plain text bytes are:
dec = {49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 49, 50, 51, 52, 53}
when I call encrypt:
enc = {4, 106, -41, 38, -127, 71, 33, 77, -125, 105, -57, 82, -13, 93, 44, -125}
and then when I call decrypt I get:
dec2 = {-103, 26, 73, -2, 64, -21, 14, -38, -51, 13, -7, 40, -83, 42, 119, -3}
dec and dec2 should have the same value but they don't!
What am I doing wrong?
I believe it might be something with converting signed char to unsigned char... I'm not sure about that piece of code where I cast directly jbyte* to unsigned char*...
Thank you!

How did you get the function signature ?
"Java_com_package_AESDecryptionFilterInputStream_encrypt( JNIEnv* env,
jobject this,
jbyte* data,
jbyte* userkey,
jint length,
jint mode)"
In JNI byte array will be passed as jbyteArray.
Function should be something like
Java_com_package_AESDecryptionFilterInputStream_encrypt( JNIEnv* env,
jobject this,
jbyteArray data,
jbyteArray userkey,
jint length,
jint mode)
You should use javah to generate the signature
You can get the length of the array passed by (*env)->GetArrayLength(env,data)
Then you have to copy into a byte* by using (*env)->GetByteArrayRegion(env, data, 0, length, nativeBytePointer);
You will probably have to allocate memory for the nativeBytePointer

Related

Self sign certificate programatically

I'm trying to build a fake HTTPS server (like mitmproxy), so I made an SSL "sign" function. after generating and installing the certificate on my system I got the error: "NET::ERR_CERT_AUTHORITY_INVALID"/ "MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT".
The code looks like
static bool generateX509(const std::shared_ptr<CA>& ca, SSL *ssl, const char * domain)
{
auto ca_cert = ca->ca_crt.get();
auto ca_pkey = ca->ca_key.get();
// --- cert generation ---
std::unique_ptr<X509, void (*)(X509 *)> cert { X509_new(), X509_free };
X509_set_notBefore(cert.get(), X509_get_notBefore(ca_cert));
X509_set_notAfter(cert.get(), X509_get_notAfter(ca_cert));
X509_set_serialNumber(cert.get(), X509_get_serialNumber(ca_cert));
X509_set_pubkey(cert.get(), X509_get_pubkey(ca_cert));
X509_set_version(cert.get(), 2);
const unsigned char country[] = "RU";
const unsigned char company[] = "MyCompany, PLC";
X509_name_st* name = X509_get_subject_name(cert.get());
X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC, country, -1, -1, 0);
X509_NAME_add_entry_by_txt(name, "O", MBSTRING_ASC, company, -1, -1, 0);
X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, (const unsigned char *)domain, -1, -1, 0);
X509_set_issuer_name(cert.get(), name);
X509_EXTENSION *Extension;
char Buffer[512];
// Format the value
sprintf (Buffer, "DNS:%s", domain);
Extension = X509V3_EXT_conf_nid (nullptr, nullptr, NID_subject_alt_name, Buffer);
if (Extension) {
X509_add_ext (cert.get(), Extension, -1);
X509_EXTENSION_free (Extension);
}
X509_sign(cert.get(), ca_pkey, EVP_sha256()); // some hash type here
SSL_use_certificate(ssl, cert.get());
SSL_use_PrivateKey(ssl, ca_pkey);
return true;
}
What i missing?
How to resolve this error

Using clBLAS on MACOSX

I just installed clBLAS on my mac (Monterey 12.4) using brew :
brew install clblas
But I can't run the simple example given by the library :
#include <sys/types.h>
#include <stdio.h>
/* Include the clBLAS header. It includes the appropriate OpenCL headers */
#include <clBLAS.h>
/* This example uses predefined matrices and their characteristics for
* simplicity purpose.
*/
#define M 4
#define N 3
#define K 5
static const cl_float alpha = 10;
static const cl_float A[M*K] = {
11, 12, 13, 14, 15,
21, 22, 23, 24, 25,
31, 32, 33, 34, 35,
41, 42, 43, 44, 45,
};
static const size_t lda = K; /* i.e. lda = K */
static const cl_float B[K*N] = {
11, 12, 13,
21, 22, 23,
31, 32, 33,
41, 42, 43,
51, 52, 53,
};
static const size_t ldb = N; /* i.e. ldb = N */
static const cl_float beta = 20;
static cl_float C[M*N] = {
11, 12, 13,
21, 22, 23,
31, 32, 33,
41, 42, 43,
};
static const size_t ldc = N; /* i.e. ldc = N */
static cl_float result[M*N];
int main( void )
{
cl_int err;
cl_platform_id platform = 0;
cl_device_id device = 0;
cl_context_properties props[3] = { CL_CONTEXT_PLATFORM, 0, 0 };
cl_context ctx = 0;
cl_command_queue queue = 0;
cl_mem bufA, bufB, bufC;
cl_event event = NULL;
int ret = 0;
/* Setup OpenCL environment. */
err = clGetPlatformIDs( 1, &platform, NULL );
err = clGetDeviceIDs( platform, CL_DEVICE_TYPE_GPU, 1, &device, NULL );
props[1] = (cl_context_properties)platform;
ctx = clCreateContext( props, 1, &device, NULL, NULL, &err );
queue = clCreateCommandQueue( ctx, device, 0, &err );
/* Setup clBLAS */
err = clblasSetup( );
/* Prepare OpenCL memory objects and place matrices inside them. */
bufA = clCreateBuffer( ctx, CL_MEM_READ_ONLY, M * K * sizeof(*A),
NULL, &err );
bufB = clCreateBuffer( ctx, CL_MEM_READ_ONLY, K * N * sizeof(*B),
NULL, &err );
bufC = clCreateBuffer( ctx, CL_MEM_READ_WRITE, M * N * sizeof(*C),
NULL, &err );
err = clEnqueueWriteBuffer( queue, bufA, CL_TRUE, 0,
M * K * sizeof( *A ), A, 0, NULL, NULL );
err = clEnqueueWriteBuffer( queue, bufB, CL_TRUE, 0,
K * N * sizeof( *B ), B, 0, NULL, NULL );
err = clEnqueueWriteBuffer( queue, bufC, CL_TRUE, 0,
M * N * sizeof( *C ), C, 0, NULL, NULL );
/* Call clBLAS extended function. Perform gemm for the lower right sub-matrices */
err = clblasSgemm( clblasRowMajor, clblasNoTrans, clblasNoTrans,
M, N, K,
alpha, bufA, 0, lda,
bufB, 0, ldb, beta,
bufC, 0, ldc,
1, &queue, 0, NULL, &event );
/* Wait for calculations to be finished. */
err = clWaitForEvents( 1, &event );
/* Fetch results of calculations from GPU memory. */
err = clEnqueueReadBuffer( queue, bufC, CL_TRUE, 0,
M * N * sizeof(*result),
result, 0, NULL, NULL );
/* Release OpenCL memory objects. */
clReleaseMemObject( bufC );
clReleaseMemObject( bufB );
clReleaseMemObject( bufA );
/* Finalize work with clBLAS */
clblasTeardown( );
/* Release OpenCL working objects. */
clReleaseCommandQueue( queue );
clReleaseContext( ctx );
return ret;
}
I get the error :
Undefined symbols for architecture x86_64:
"_clblasSetup", referenced from:
_main in main.o
"_clblasSgemm", referenced from:
_main in main.o
"_clblasTeardown", referenced from:
_main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [Program] Error 1
I know this is a linker problem but I don't know how to solve it. I'm including OpenCL like I do for other project :
LDFLAGS=-framework OpenCL
I tried variations around :
LDFLAGS=-framework OpenCL -framework clblas
But nothing works. Sorry if the question is simple.
EDIT : I found with this question that cblas.h is in a
-framework Accelerate
But still no possibility to find clblas.h
I found the solution which was quite simple.
We only need to add the library in the makefile :
/usr/local/Cellar/clblas/2.12/lib/libclBLAS.dylib
And add the path to the header :
/usr/local/Cellar/clblas/2.12/include/
Paths may depend on your installation.

Passing a byte array to WMI provider class in C++

I have an implementation of WMI client application in C++. I am looking to call ProtectKeyWithExternalKey method of the Win32_EncryptableVolume class. It takes a byte array as parameter (ExternalKey).
uint32 ProtectKeyWithExternalKey(
[in, optional] string FriendlyName,
[in, optional] uint8 ExternalKey[],
[out] string VolumeKeyProtectorID
);
When this method will be called using ExecMethod of IWbemServices class, we need to set IWbemClassObject object for input params and pass to ExecMethod.
virtual HRESULT STDMETHODCALLTYPE ExecMethod(
/* [in] */ __RPC__in const BSTR strObjectPath,
/* [in] */ __RPC__in const BSTR strMethodName,
/* [in] */ long lFlags,
/* [in] */ __RPC__in_opt IWbemContext *pCtx,
/* [in] */ __RPC__in_opt IWbemClassObject *pInParams,
/* [unique][in][out] */ __RPC__deref_opt_inout_opt IWbemClassObject **ppOutParams,
/* [unique][in][out] */ __RPC__deref_opt_inout_opt IWbemCallResult **ppCallResult) = 0;
While setting IWbemClassObject, VARIANT type needs to be set.
virtual HRESULT STDMETHODCALLTYPE Put(
/* [string][in] */ LPCWSTR wszName,
/* [in] */ long lFlags,
/* [in] */ VARIANT *pVal,
/* [in] */ CIMTYPE Type) = 0;
What should be set to VARIANT (VARTYPE and member of union) for byte array (uint8[])?
typedef /* [wire_marshal] */ struct tagVARIANT VARIANT;
struct tagVARIANT
{
union
{
struct __tagVARIANT
{
VARTYPE vt;
WORD wReserved1;
WORD wReserved2;
WORD wReserved3;
union
{
LONGLONG llVal;
LONG lVal;
BYTE bVal;
SHORT iVal;
FLOAT fltVal;
DOUBLE dblVal;
VARIANT_BOOL boolVal;
_VARIANT_BOOL bool;
SCODE scode;
CY cyVal;
DATE date;
BSTR bstrVal;
IUnknown *punkVal;
IDispatch *pdispVal;
SAFEARRAY *parray;
BYTE *pbVal;
SHORT *piVal;
LONG *plVal;
LONGLONG *pllVal;
FLOAT *pfltVal;
DOUBLE *pdblVal;
VARIANT_BOOL *pboolVal;
_VARIANT_BOOL *pbool;
SCODE *pscode;
CY *pcyVal;
DATE *pdate;
BSTR *pbstrVal;
IUnknown **ppunkVal;
IDispatch **ppdispVal;
SAFEARRAY **pparray;
VARIANT *pvarVal;
PVOID byref;
CHAR cVal;
USHORT uiVal;
ULONG ulVal;
ULONGLONG ullVal;
INT intVal;
UINT uintVal;
DECIMAL *pdecVal;
CHAR *pcVal;
USHORT *puiVal;
ULONG *pulVal;
ULONGLONG *pullVal;
INT *pintVal;
UINT *puintVal;
struct __tagBRECORD
{
PVOID pvRecord;
IRecordInfo *pRecInfo;
} __VARIANT_NAME_4;
} __VARIANT_NAME_3;
} __VARIANT_NAME_2;
DECIMAL decVal;
} __VARIANT_NAME_1;
} ;
Should it be BYTE* for union member? If yes, that would be pointer to unsigned char. How the size of byte array determined? Is it by null char for end of array? In other words, for passing byte array, is uint8* sufficient and size of array is not required?
And what should be initialized to VARTYPE member? Here is the enum.
enum VARENUM
{
VT_EMPTY = 0,
VT_NULL = 1,
VT_I2 = 2,
VT_I4 = 3,
VT_R4 = 4,
VT_R8 = 5,
VT_CY = 6,
VT_DATE = 7,
VT_BSTR = 8,
VT_DISPATCH = 9,
VT_ERROR = 10,
VT_BOOL = 11,
VT_VARIANT = 12,
VT_UNKNOWN = 13,
VT_DECIMAL = 14,
VT_I1 = 16,
VT_UI1 = 17,
VT_UI2 = 18,
VT_UI4 = 19,
VT_I8 = 20,
VT_UI8 = 21,
VT_INT = 22,
VT_UINT = 23,
VT_VOID = 24,
VT_HRESULT = 25,
VT_PTR = 26,
VT_SAFEARRAY = 27,
VT_CARRAY = 28,
VT_USERDEFINED = 29,
VT_LPSTR = 30,
VT_LPWSTR = 31,
VT_RECORD = 36,
VT_INT_PTR = 37,
VT_UINT_PTR = 38,
VT_FILETIME = 64,
VT_BLOB = 65,
VT_STREAM = 66,
VT_STORAGE = 67,
VT_STREAMED_OBJECT = 68,
VT_STORED_OBJECT = 69,
VT_BLOB_OBJECT = 70,
VT_CF = 71,
VT_CLSID = 72,
VT_VERSIONED_STREAM = 73,
VT_BSTR_BLOB = 0xfff,
VT_VECTOR = 0x1000,
VT_ARRAY = 0x2000,
VT_BYREF = 0x4000,
VT_RESERVED = 0x8000,
VT_ILLEGAL = 0xffff,
VT_ILLEGALMASKED = 0xfff,
VT_TYPEMASK = 0xfff
} ;
Should it be VT_BLOB?
VT_BLOB [P] Length prefixed bytes
Please help. Thanks in advance!

Encrypt and Decrypt some string in C++ And Delphi

I have the following code in Delphi XE2 to Encrypt and Decrypt a String.
What is wrong is that I get different encrypt Results ? I need to read and write some string in both languages Delphi and C++, and I do not want use a DLL writing in Delphi to do It in C++
function CryptString(Const Input: string; password : AnsiString; Encrypt: Boolean) : string;
const
BufferSize=1024*1024;
var
StreamSource : TStringStream;
StreamDest : TStringStream;
CRYPTPROV : HCRYPTPROV;
CRYPTHASH : HCRYPTHASH;
CRYPTKEY : HCRYPTKEY;
Buffer : LPBYTE;
BytesIn : DWORD;
Final : Boolean;
Encoder : TIdEncoderMIME;
Decoder : TIdDecoderMIME;
DestStream : TStringStream;
begin
CryptAcquireContext(CRYPTPROV, nil, MS_DEF_DH_SCHANNEL_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
try
//create a valid key based in the password
if not CryptCreateHash(CRYPTPROV, CALG_SHA1, 0, 0, CRYPTHASH) then RaiseLastOSError;
try
if not CryptHashData(CRYPTHASH, #Password[1], Length(Password), 0) then RaiseLastOSError;
if not CryptDeriveKey(CRYPTPROV, CALG_RC4, CRYPTHASH, 0, CRYPTKEY) then RaiseLastOSError;
finally
CryptDestroyHash(CRYPTHASH);
end;
StreamSource := TStringStream.Create(Input);
StreamSource.Position := 0;
StreamDest := TStringStream.Create;
try
GetMem(Buffer, BufferSize);
try
if not Encrypt then
begin
//decode the string using base64
Decoder := TIdDecoderMIME.Create(nil);
try
DestStream := TStringStream.Create;
try
StreamDest.Position:=0;
Decoder.DecodeBegin(DestStream);
Decoder.Decode(StreamSource);
Decoder.DecodeEnd;
StreamSource.Clear;
DestStream.Position:=0;
StreamSource.CopyFrom(DestStream,DestStream.Size);
StreamSource.Position:=0;
finally
FreeAndNil( DestStream);
end;
finally
FreeAndNil( Decoder);
end;
end;
repeat
BytesIn := StreamSource.Read(Buffer^, BufferSize);
Final := (StreamSource.Position >= StreamSource.Size);
if Encrypt then begin
if not CryptEncrypt(CRYPTKEY, 0, Final, 0, Buffer, BytesIn, BytesIn) then
RaiseLastOSError;
end
else if not CryptDecrypt(CRYPTKEY, 0, Final, 0, Buffer, BytesIn) then
RaiseLastOSError;
StreamDest.Write(Buffer^, BytesIn);
until Final;
//encode the string using base64
if Encrypt then
begin
Encoder := TIdEncoderMIME.Create(nil);
try
DestStream:=TStringStream.Create;
try
StreamDest.Position:=0;
Encoder.Encode(StreamDest,DestStream);
Result := DestStream.DataString;
finally
FreeAndNil( DestStream);
end;
finally
FreeAndNil(Encoder);
end;
end
else
Result:= StreamDest.DataString;
finally
FreeMem(Buffer, BufferSize);
end;
finally
FreeAndNil( StreamSource);
FreeAndNil( StreamDest);
end;
finally
CryptReleaseContext(CRYPTPROV, 0);
end;
end;
I found the following code in C++ to make the same thing, but the encryption results are different.
int main()
{
const char* passw = "teste";
const char* toencrypt = "sa";
HCRYPTPROV hProv;
HCRYPTHASH hHash;
HCRYPTKEY hKey;
DWORD todwSize = (DWORD)strlen(toencrypt);
PBYTE pBuffer;
CryptAcquireContext(&hProv, NULL, NULL , PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
CryptCreateHash(hProv, CALG_SHA1 , 0, 0, &hHash);
CryptHashData(hHash, (BYTE*)passw, strlen(passw), 0);
CryptDeriveKey(hProv, CALG_RC4, hHash, 0, &hKey);
CryptDestroyHash(hHash);
//--------------------------------------------------------------------
pBuffer = (BYTE *)malloc(todwSize);
strcpy((char*)pBuffer, toencrypt);
CryptEncrypt(hKey, 0, TRUE, 0, pBuffer, &todwSize, todwSize);
PBYTE pBreturn = pBuffer;
const char* message = (const char*)pBreturn;
printf("%s", message);
system("pause");
//--------------------------------------------------------------------
DWORD dwSize = (DWORD)strlen(message);
PBYTE depBuffer;
depBuffer = (BYTE *)malloc(1460);
strcpy((char*)depBuffer, message);
CryptDecrypt(hKey, 0, TRUE, 0, depBuffer, &dwSize);
CryptDestroyKey(hKey);
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, 0);
if (GetLastError() != 0)
{
printf("%d", GetLastError());
}
PBYTE depBreturn = depBuffer;
printf("%s", (const char*)depBreturn);
printf("\n%d", strlen(message));
return 0;
}
This code bellow Show how Encrypt string, decrypt string, and encrypt string and decrypt string convert to base64 like Delphi code above do. in Vc++
Part of this code is based on CryptEncrypt does not encrypt whole text
#include "stdafx.h"
#include <atlenc.h>
#include <atlstr.h>
#include <locale.h>
static const unsigned char pr2six[256] =
{
/* ASCII table */
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64,
64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64,
64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
};
int Base64decode_len(const char *bufcoded)
{
int nbytesdecoded;
register const unsigned char *bufin;
register int nprbytes;
bufin = (const unsigned char *)bufcoded;
while (pr2six[*(bufin++)] <= 63);
nprbytes = (bufin - (const unsigned char *)bufcoded) - 1;
nbytesdecoded = ((nprbytes + 3) / 4) * 3;
return nbytesdecoded + 1;
}
int Base64decode(char *bufplain, const char *bufcoded)
{
int nbytesdecoded;
register const unsigned char *bufin;
register unsigned char *bufout;
register int nprbytes;
bufin = (const unsigned char *)bufcoded;
while (pr2six[*(bufin++)] <= 63);
nprbytes = (bufin - (const unsigned char *)bufcoded) - 1;
nbytesdecoded = ((nprbytes + 3) / 4) * 3;
bufout = (unsigned char *)bufplain;
bufin = (const unsigned char *)bufcoded;
while (nprbytes > 4) {
*(bufout++) =
(unsigned char)(pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
*(bufout++) =
(unsigned char)(pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
*(bufout++) =
(unsigned char)(pr2six[bufin[2]] << 6 | pr2six[bufin[3]]);
bufin += 4;
nprbytes -= 4;
}
/* Note: (nprbytes == 1) would be an error, so just ingore that case */
if (nprbytes > 1) {
*(bufout++) =
(unsigned char)(pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
}
if (nprbytes > 2) {
*(bufout++) =
(unsigned char)(pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
}
if (nprbytes > 3) {
*(bufout++) =
(unsigned char)(pr2six[bufin[2]] << 6 | pr2six[bufin[3]]);
}
*(bufout++) = '\0';
nbytesdecoded -= (4 - nprbytes) & 3;
return nbytesdecoded;
}
static const char basis_64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int Base64encode_len(int len)
{
return ((len + 2) / 3 * 4) + 1;
}
int Base64encode(char *encoded, const char *string, int len)
{
int i;
char *p;
p = encoded;
for (i = 0; i < len - 2; i += 3) {
*p++ = basis_64[(string[i] >> 2) & 0x3F];
*p++ = basis_64[((string[i] & 0x3) << 4) |
((int)(string[i + 1] & 0xF0) >> 4)];
*p++ = basis_64[((string[i + 1] & 0xF) << 2) |
((int)(string[i + 2] & 0xC0) >> 6)];
*p++ = basis_64[string[i + 2] & 0x3F];
}
if (i < len) {
*p++ = basis_64[(string[i] >> 2) & 0x3F];
if (i == (len - 1)) {
*p++ = basis_64[((string[i] & 0x3) << 4)];
*p++ = '=';
}
else {
*p++ = basis_64[((string[i] & 0x3) << 4) |
((int)(string[i + 1] & 0xF0) >> 4)];
*p++ = basis_64[((string[i + 1] & 0xF) << 2)];
}
*p++ = '=';
}
*p++ = '\0';
return p - encoded;
}
bool encryptStr(const char *pSourceTxt,const char* pKey, int length, char * pEncryptTxt)
{
HCRYPTPROV hProv;
HCRYPTHASH hHash;
HCRYPTKEY hKey;
DWORD todwSize = (DWORD)strlen(pSourceTxt), needSize;
PBYTE pBuffer;
char *txtBuf = (char *)_alloca(todwSize + 1);
if (CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
{
if (CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash))
{
if (CryptHashData(hHash, (BYTE*)pKey, (DWORD)strlen(pKey), 0) &&
CryptDeriveKey(hProv, CALG_RC4, hHash, 0, &hKey))
{
if (CryptEncrypt(hKey, 0, TRUE, 0, NULL, &(needSize = todwSize), 0))
{
memcpy(pBuffer = (BYTE *)_alloca(needSize), pSourceTxt, todwSize);
if (CryptEncrypt(hKey, 0, TRUE, 0, pBuffer, &todwSize, needSize))
{
txtBuf[todwSize] = NULL;
memcpy(txtBuf, pBuffer, todwSize);
memcpy(pEncryptTxt, txtBuf, todwSize + 1);
}
}
CryptDestroyKey(hKey);
}
CryptDestroyHash(hHash);
}
CryptReleaseContext(hProv, 0);
}
return true;
}
bool encryptStrBase64(const char *pSourceTxt, const char* pKey, int length, char * pEncryptTxt)
{
HCRYPTPROV hProv;
HCRYPTHASH hHash;
HCRYPTKEY hKey;
DWORD todwSize = (DWORD)strlen(pSourceTxt), needSize;
PBYTE pBuffer;
char *txtBuf = (char *)_alloca(todwSize + 1);
if (CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
{
if (CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash))
{
if (CryptHashData(hHash, (BYTE*)pKey, (DWORD)strlen(pKey), 0) &&
CryptDeriveKey(hProv, CALG_RC4, hHash, 0, &hKey))
{
if (CryptEncrypt(hKey, 0, TRUE, 0, NULL, &(needSize = todwSize), 0))
{
memcpy(pBuffer = (BYTE *)_alloca(needSize), pSourceTxt, todwSize);
if (CryptEncrypt(hKey, 0, TRUE, 0, pBuffer, &todwSize, needSize))
{
txtBuf[todwSize] = NULL;
memcpy(txtBuf, pBuffer, todwSize);
char *txtEncode64 = (char *)_alloca(strlen(pEncryptTxt));
Base64encode(txtEncode64, txtBuf, todwSize);
memcpy(pEncryptTxt, txtEncode64, todwSize +100);
}
}
CryptDestroyKey(hKey);
}
CryptDestroyHash(hHash);
}
CryptReleaseContext(hProv, 0);
}
return true;
}
bool decryptStr(const char *pEncryptTxt, const char* pKey, int length, char * pDecryptTxt)
{
HCRYPTPROV hProv;
HCRYPTHASH hHash;
HCRYPTKEY hKey;
DWORD todwSize = (DWORD)strlen(pEncryptTxt);
PBYTE pBuffer = (BYTE *)_alloca(todwSize);
char *txtBuf = (char *)_alloca(todwSize + 1);
if (CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
{
if (CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash))
{
if (CryptHashData(hHash, (BYTE*)pKey, (DWORD)strlen(pKey), 0) &&
CryptDeriveKey(hProv, CALG_RC4, hHash, 0, &hKey))
{
memcpy(pBuffer, pEncryptTxt, todwSize);
if (CryptDecrypt(hKey, 0, TRUE, 0, pBuffer, &todwSize))
{
txtBuf[todwSize] = NULL;
memcpy(txtBuf, pBuffer, todwSize);
memcpy(pDecryptTxt, txtBuf, todwSize + 1);
}
CryptDestroyKey(hKey);
}
CryptDestroyHash(hHash);
}
CryptReleaseContext(hProv, 0);
}
return true;
}
bool decryptStrBase64(const char *pEncryptTxt, const char* pKey, int length, char * pDecryptTxt)
{
HCRYPTPROV hProv;
HCRYPTHASH hHash;
HCRYPTKEY hKey;
char *sourceTxt = (char *)_alloca(2048);
Base64decode(sourceTxt, pEncryptTxt);
DWORD todwSize = (DWORD)strlen(sourceTxt);
PBYTE pBuffer = (BYTE *)_alloca(todwSize);
char *txtBuf = (char *)_alloca(todwSize + 1);
if (CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
{
if (CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash))
{
if (CryptHashData(hHash, (BYTE*)pKey, (DWORD)strlen(pKey), 0) &&
CryptDeriveKey(hProv, CALG_RC4, hHash, 0, &hKey))
{
memcpy(pBuffer, sourceTxt, todwSize);
if (CryptDecrypt(hKey, 0, TRUE, 0, pBuffer, &todwSize))
{
txtBuf[todwSize] = NULL;
memcpy(txtBuf, pBuffer, todwSize);
memcpy(pDecryptTxt, txtBuf, todwSize + 1);
}
CryptDestroyKey(hKey);
}
CryptDestroyHash(hHash);
}
CryptReleaseContext(hProv, 0);
}
return true;
}
int main()
{
char* encryptWord = "test word";
char *encryptKey = "cryptkey";
int encryptLen = strlen(encryptWord);
char * txtEncrypt = (char *)_alloca(encryptLen+1);
//simple Encrypt TXT
encryptStr(encryptWord, encryptKey, encryptLen,txtEncrypt);
printf("Simple Encrypt %s \n", txtEncrypt);
//Decrypt string
char* decryptTxt = (char *)_alloca(encryptLen + 1);
decryptStr(txtEncrypt, encryptKey, encryptLen, decryptTxt);
printf("Txt decrypted %s \n", decryptTxt);
//Encrypt and Convert to Base64 like delphi Routine
char* base64TxtEncrypt = (char*)_alloca(encryptLen + 100);//need aloc more size due base64 routine
encryptStrBase64(encryptWord, encryptKey, encryptLen, base64TxtEncrypt);
printf("Base64 txt encrypted %s \n", base64TxtEncrypt);
//decrypt and Convert to original String like delphi Routine
char* base64TxtDecrypt = (char*)_alloca(encryptLen + 100);
decryptStrBase64( base64TxtEncrypt, encryptKey, strlen(base64TxtEncrypt) , base64TxtDecrypt);
printf("Base64 txt Decrypted %s \n", base64TxtDecrypt);
system("pause");
return 0;
}
And finally the conversion of this code to c#, and mission end
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
namespace CryptCsharpNativo
{
class Program
{
public const uint PROV_RSA_FULL = 1;
public const uint CRYPT_VERIFYCONTEXT = 0xF0000000;
public const uint CRYPT_NEWKEYSET = 0x00000008;
public enum ALG_ID
{
CALG_MD5 = 0x00008003,
CALG_RC4 = 0x00006801,
CALG_SHA1 = 0x00008004
}
[DllImport("advapi32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptAcquireContext(out IntPtr phProv, string pszContainer, string pszProvider, uint dwProvType, uint dwFlags);
[DllImport("advapi32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptCreateHash(IntPtr hProv, ALG_ID Algid, IntPtr hKey, uint dwFlags, out IntPtr phHash);
[DllImport("advapi32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptHashData(IntPtr hHash, byte[] pbData, int dwDataLen, uint dwFlags);
[DllImport("advapi32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptDeriveKey(IntPtr hProv, ALG_ID Algid, IntPtr hBaseData, uint dwFlags, ref IntPtr phKey);
[DllImport("advapi32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptDestroyHash(IntPtr hHash);
[DllImport("advapi32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptEncrypt(IntPtr hKey, IntPtr hHash, [MarshalAs(UnmanagedType.Bool)]bool Final, uint dwFlags, byte[] pbData, ref int pdwDataLen);
[DllImport("advapi32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptDecrypt(IntPtr hKey, IntPtr hHash, [MarshalAs(UnmanagedType.Bool)]bool Final, uint dwFlags, byte[] pbData, ref int pdwDataLen);
[DllImport("advapi32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptDestroyKey(IntPtr hKey);
[DllImport("advapi32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptReleaseContext(IntPtr hProv, uint dwFlags);
const uint NTE_BAD_KEYSET = 0x80090016;
public static string decryptStr(string pSourceTxt, string pKey)
{
IntPtr hCryptProv;
IntPtr hKey = IntPtr.Zero;
IntPtr hHash;
int dwCount = 0;
byte[] key = Encoding.ASCII.GetBytes(pKey);
int datalen = pSourceTxt.Length;
// Get a handle to the default provider.
if (!CryptAcquireContext(out hCryptProv, null, null, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
{
return "";
}
// Decrypt the file with a session key derived from a password.
// Create a hash object.
if (!CryptCreateHash(hCryptProv, ALG_ID.CALG_SHA1, IntPtr.Zero, 0, out hHash))
return "";
// Hash in the password data.
if (!CryptHashData(hHash, key, key.Length, 0))
return "";
// Derive a session key from the hash object.
if (!CryptDeriveKey(hCryptProv, ALG_ID.CALG_RC4, hHash, 0, ref hKey))
return "";
// Destroy the hash object.
if (!(CryptDestroyHash(hHash)))
return "";
hHash = IntPtr.Zero;
byte[] originalCrypt = Convert.FromBase64String(pSourceTxt);
if (!CryptDecrypt(hKey, IntPtr.Zero, true, 0, originalCrypt, ref datalen))
return "";
datalen = dwCount;
// Destroy session key.
if (hKey != IntPtr.Zero)
{
if (!(CryptDestroyKey(hKey)))
return "";
}
// Release provider handle.
if (hCryptProv != IntPtr.Zero)
{
if (!(CryptReleaseContext(hCryptProv, 0)))
return "";
}
return Encoding.ASCII.GetString(originalCrypt);
} // end Decryptfile
public static string encryptStr(string pSourceTxt, string pKey)
{
IntPtr hCryptProv;
IntPtr hKey = IntPtr.Zero;
IntPtr hHash;
int dwCount = 0;
byte[] sourceTxt = Encoding.ASCII.GetBytes(pSourceTxt);
byte[] key = Encoding.ASCII.GetBytes(pKey);
int datalen = pSourceTxt.Length;
// Get a handle to the default provider.
if (!CryptAcquireContext(out hCryptProv, null, null, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
{
return "";
}
// Decrypt the file with a session key derived from a password.
// Create a hash object.
if (!CryptCreateHash(hCryptProv, ALG_ID.CALG_SHA1, IntPtr.Zero, 0, out hHash))
return "";
// Hash in the password data.
if (!CryptHashData(hHash, key, key.Length, 0))
return "";
// Derive a session key from the hash object.
if (!CryptDeriveKey(hCryptProv, ALG_ID.CALG_RC4 , hHash, 0, ref hKey))
return "";
// Destroy the hash object.
if (!(CryptDestroyHash(hHash)))
return "";
hHash = IntPtr.Zero;
if (!CryptEncrypt(hKey, IntPtr.Zero, true, 0, null, ref datalen))
return "";
if (!CryptEncrypt(hKey, IntPtr.Zero, true, 0, sourceTxt, ref datalen))
return "";
string base64 = Convert.ToBase64String(sourceTxt);
datalen = dwCount;
// Destroy session key.
if (hKey != IntPtr.Zero)
{
if (!(CryptDestroyKey(hKey)))
return "";
}
// Release provider handle.
if (hCryptProv != IntPtr.Zero)
{
if (!(CryptReleaseContext(hCryptProv, 0)))
return "";
}
return base64;
} // end encryptfile
static void Main(string[] args)
{
string encryptTxt = "Teste Crypt";
string key = "teste123";
string encryptStr = Program.encryptStr(encryptTxt, key);
string decryptStr = Program.decryptStr(encryptStr, key);
Console.Write("Encrypt String with Base64 = {0} \n" , encryptStr);
Console.Write("Decrypted String with base64 = {0}", decryptStr);
Console.ReadLine();
}
}
}

Sql Like similar use in c++

I would like to ask a simple question, is there any way to use "like" such thing in c++
LIKE '%s I want some thing like this in c++ because if I want user to find something in the program, this simply matches all the related data.
Regular expressions can be used to achieve what you want. There are two problems, though:
1.) They are really complicated to use compared to the simple SQL LIKE keyword.
2.) They are only a standard feature in C++11. If you write in "old" C++, then you'd have to use the Boost.Regex library.
However...
Looking at the very basic LIKE examples at w3schools.com, you could in fact implement many of them in simple C++, using normal std::string functions.
For instance, let's have a look a this:
SELECT * FROM Customers WHERE City LIKE '%s';
This just means that for every string, you look at the last character and check if it's 's':
std::string s;
// ...
if (!s.empty() && (s[s.size() - 1] == 's') {
// ...
}
Or this:
SELECT * FROM Customers WHERE Country NOT LIKE '%land%';
In C++:
std::string s;
// ...
if (s.find("land") == std::string::npos) {
// ...
}
So, in the end, it really depends on what exactly you'd want to do with LIKE.
You could try using boost's string algorithm library, which can be used with std::string. It also gives you the option of using C++11 regular expressions. There are lots of functions for doing useful things (see the docs), such as starts_with() (or istarts_with() for case insensitive version)
This is version copied from SQL Lite.
Now you can use: patternCompare("A*A","AxA");
//---------------------LIKE------------------------------
/*
** This lookup table is used to help decode the first byte of
** a multi-byte UTF8 character.
*/
static const unsigned char sqlite3Utf8Trans1[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x00, 0x00,
};
typedef unsigned int u32;
typedef unsigned char u8;
u32 sqlite3Utf8Read(
const unsigned char **pz /* Pointer to string from which to read char */
){
unsigned int c;
/* Same as READ_UTF8() above but without the zTerm parameter.
** For this routine, we assume the UTF8 string is always zero-terminated.
*/
c = *((*pz)++);
if (c >= 0xc0){
c = sqlite3Utf8Trans1[c - 0xc0];
while ((*(*pz) & 0xc0) == 0x80){
c = (c << 6) + (0x3f & *((*pz)++));
}
if (c<0x80
|| (c & 0xFFFFF800) == 0xD800
|| (c & 0xFFFFFFFE) == 0xFFFE){
c = 0xFFFD;
}
}
return c;
}
/*
** Assuming zIn points to the first byte of a UTF-8 character,
** advance zIn to point to the first byte of the next UTF-8 character.
*/
#define SQLITE_SKIP_UTF8(zIn) { \
if( (*(zIn++))>=0xc0 ){ \
while( (*zIn & 0xc0)==0x80 ){ zIn++; } \
} \
}
const unsigned char sqlite3UpperToLower[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 97, 98, 99, 100, 101, 102, 103,
104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121,
122, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107,
108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125,
126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161,
162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179,
180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197,
198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215,
216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233,
234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251,
252, 253, 254, 255
};
# define GlobUpperToLower(A) if( !((A)&~0x7f) ){ A = sqlite3UpperToLower[A]; }
/*
** Compare two UTF-8 strings for equality where the first string can
** potentially be a "glob" expression. Return true (1) if they
** are the same and false (0) if they are different.
**
** Globbing rules:
**
** '*' Matches any sequence of zero or more characters.
**
** '?' Matches exactly one character.
**
** [...] Matches one character from the enclosed list of
** characters.
**
** [^...] Matches one character not in the enclosed list.
**
** With the [...] and [^...] matching, a ']' character can be included
** in the list by making it the first character after '[' or '^'. A
** range of characters can be specified using '-'. Example:
** "[a-z]" matches any single lower-case letter. To match a '-', make
** it the last character in the list.
**
** This routine is usually quick, but can be N**2 in the worst case.
**
** Hints: to match '*' or '?', put them in "[]". Like this:
**
** abc[*]xyz Matches "abc*xyz" only
*/
static int patternCompare(
const u8 *zPattern, /* The glob pattern */
const u8 *zString
)
{
u32 c, c2;
int invert;
int seen;
const u8 matchOne = '?';
const u8 matchAll = '*';
const u8 matchSet = '[';
const u8 noCase =0;
int prevEscape = 0; /* True if the previous character was 'escape' */
u32 esc = 0;
//u32 esc; /* The escape character */
while ((c = sqlite3Utf8Read(&zPattern)) != 0){
if (c == matchAll && !prevEscape){
while ((c = sqlite3Utf8Read(&zPattern)) == matchAll
|| c == matchOne){
if (c == matchOne && sqlite3Utf8Read(&zString) == 0){
return 0;
}
}
if (c == 0){
return 1;
}
else if (c == esc){
c = sqlite3Utf8Read(&zPattern);
if (c == 0){
return 0;
}
}
else if (c == matchSet){
//assert(esc == 0); /* This is GLOB, not LIKE */
//assert(matchSet<0x80); /* '[' is a single-byte character */
while (*zString && patternCompare(&zPattern[-1], zString) == 0){
SQLITE_SKIP_UTF8(zString);
}
return *zString != 0;
}
while ((c2 = sqlite3Utf8Read(&zString)) != 0){
if (noCase){
GlobUpperToLower(c2);
GlobUpperToLower(c);
while (c2 != 0 && c2 != c){
c2 = sqlite3Utf8Read(&zString);
GlobUpperToLower(c2);
}
}
else{
while (c2 != 0 && c2 != c){
c2 = sqlite3Utf8Read(&zString);
}
}
if (c2 == 0) return 0;
if (patternCompare(zPattern, zString)) return 1;
}
return 0;
}
else if (c == matchOne && !prevEscape){
if (sqlite3Utf8Read(&zString) == 0){
return 0;
}
}
else if (c == matchSet){
u32 prior_c = 0;
//assert(esc == 0); /* This only occurs for GLOB, not LIKE */
seen = 0;
invert = 0;
c = sqlite3Utf8Read(&zString);
if (c == 0) return 0;
c2 = sqlite3Utf8Read(&zPattern);
if (c2 == '^'){
invert = 1;
c2 = sqlite3Utf8Read(&zPattern);
}
if (c2 == ']'){
if (c == ']') seen = 1;
c2 = sqlite3Utf8Read(&zPattern);
}
while (c2 && c2 != ']'){
if (c2 == '-' && zPattern[0] != ']' && zPattern[0] != 0 && prior_c>0){
c2 = sqlite3Utf8Read(&zPattern);
if (c >= prior_c && c <= c2) seen = 1;
prior_c = 0;
}
else{
if (c == c2){
seen = 1;
}
prior_c = c2;
}
c2 = sqlite3Utf8Read(&zPattern);
}
if (c2 == 0 || (seen ^ invert) == 0){
return 0;
}
}
else if (esc == c && !prevEscape){
prevEscape = 1;
}
else{
c2 = sqlite3Utf8Read(&zString);
if (noCase){
GlobUpperToLower(c);
GlobUpperToLower(c2);
}
if (c != c2){
return 0;
}
prevEscape = 0;
}
}
return *zString == 0;
}
http://www.cplusplus.com/reference/regex/regex_match/ has an example of what you want to do. See lines 9-10 of the code near the bottom.