openssl提供了强大的加解密功能,本文利用openssl实现了一个AES_128_CBC功能,结果用base64编码输出。
代码如下:
#include <openssl/hmac.h>
#include <openssl/bio.h>
#include <openssl/buffer.h>
#include <unistd.h>
#include <sys/types.h>
#include <android/log.h>
#include <linux/binder.h>
#include <stdio.h>
#include <stdlib.h>
#include <asm/ptrace.h>
#include <asm/user.h>
#include <asm/ptrace.h>
#include <sys/wait.h>
#include <sys/mman.h>
#include <dlfcn.h>
#include <dirent.h>
#include <string.h>
#include <jni.h>
#include <android/log.h>
#include <sys/system_properties.h>
#include <openssl/evp.h>
#include <openssl/sha.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <linux/stat.h>
#include <sys/stat.h>
/* Encode a string to base64 and return it */
int base64_encode(char *string, int length,char *encode)
{
BIO *bmem=NULL, *b64=NULL;
BUF_MEM *bptr=NULL;
b64 = BIO_new(BIO_f_base64());
bmem = BIO_new(BIO_s_mem());
b64 = BIO_push(b64, bmem);
BIO_write(b64, string, length);
BIO_flush(b64);
BIO_get_mem_ptr(b64, &bptr);
sprintf(encode, "%s", bptr->data);
encode[bptr->length-1] = '\0';
BIO_free_all(b64);
return bptr->length-1;
}
/* Decode a string to plain text and return it */
int base64_decode(unsigned char *input, int length,unsigned char* output)
{
BIO *b64, *bmem;
//char *buffer = (char *)malloc(strlen(input));
//memset(buffer, 0, length);
b64 = BIO_new(BIO_f_base64());
bmem = BIO_new_mem_buf(input, length);
bmem = BIO_push(b64, bmem);
BIO_read(bmem, output, length);
BIO_free_all(bmem);
return strlen(output);
}
int encrypt_base64(const unsigned char *key,const unsigned char *plaintext,int plaintext_len,unsigned char *out_base64)
{
unsigned char out[2000]="\0";
int outlen, flen, total =0;
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
const EVP_CIPHER *cipher = EVP_aes_128_cbc();
char iv[16]={12, 34, 56, 78, 90,87, 65, 43,23,54,18,9,4,23,5,6};
//unsigned char iv[16]="\0";
printf("key is %s\n",key);
if(!EVP_EncryptInit(&ctx, cipher, key, iv)){
return -1;//error
}
if(!EVP_EncryptUpdate(&ctx, out, &outlen, plaintext, plaintext_len)){
return -1;
}
EVP_CIPHER_CTX_cleanup(&ctx);
printf("outlen is %d\n",outlen);
outlen +=flen;
printf("flen is %d\n",flen);
printf("outlen is %d\n",outlen);
int i=0;
for(i=0;i<outlen;i++){
printf("%02x",out[i]);
}
printf("\n");
total = base64_encode(out,outlen,out_base64);
if(total <= 1)//encode error
return 0;
return total;
}
int decrypt_base64(const unsigned char *key,const unsigned char *cipher_text_base64,unsigned char *de)
{
int ret;
EVP_CIPHER_CTX ctx2;
const EVP_CIPHER *cipher;
int i,len,inl,outl,total=0;
unsigned char iv[16]={12, 34, 56, 78, 90,87, 65, 43,23,54,18,9,4,23,5,6};
unsigned char cipher_text[2000];
int base64_decode_len = base64_decode((unsigned char *)cipher_text_base64,strlen(cipher_text_base64),cipher_text);
printf("base64_decode_len is %d\n",base64_decode_len);
LOGI("base64_decode_len=%d\n",base64_decode_len);
if(base64_decode_len == -1)
{
LOGI("err base64_decode_len = %d\n",base64_decode_len);
return -1;
}
cipher=EVP_aes_128_cbc();
EVP_CIPHER_CTX_init(&ctx2);
ret=EVP_DecryptInit_ex(&ctx2,cipher,NULL,key,iv);
if(ret!=1)
{
LOGI("EVP_DecryptInit_ex err1!\n");
return -1;
}
total=0;
EVP_DecryptUpdate(&ctx2,de+total,&outl,cipher_text,base64_decode_len);
total+=outl;
if(ret!=1)
{
EVP_CIPHER_CTX_cleanup(&ctx2);
LOGI("EVP_DecryptFinal_ex err\n");
return -1;
}
de[128] = '\0';
LOGI("de=%s;\n",de);
EVP_CIPHER_CTX_cleanup(&ctx2);
return 1;
}
int main(){
unsigned char key2[33]= "1234567890123455";
unsigned char in[129]= "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678";
unsigned char out_base64[512] = "\n";
unsigned char de[129]="\0";
encrypt_base64(key2,in,strlen(in),out_base64);
printf("out_base64=%s\n",(char *)out_base64);
decrypt_base64(key2,out_base64,de);
printf("de=%s\n",(char *)de);
return 0;
}
另外说明一下:EVP_EncryptFinal并不是随便用的,只有一串字符不是16的倍数,后面需要padding时,调用EVP_EncryptFinal去处理最后一串字符的时候才用。而且base64字符串要是超过一定长度,会自动拼接回车的。
执行的结果如下:
root@generic_x86:/data/data # ./encryption
./encryption
key is 1234567890123455
outlen is 128
flen is 0
outlen is 128
1d9d9d361719819cf6383d78059ae1214a19253b64311d851fcfa96a8d109f3d9c9688ab4f1bf97201df6f8854de86ce522f583e92a4b965d496ce74bbf788af7fceff12e9ce9e96fe695c40ec47d203a8d07e515199abe4981167bca4c7c97234fffcbcef02d5b5d75335c2bd801c776ede4ba48e134f8a5efaef974050
6784
out_base64=HZ2dNhcZgZz2OD14BZrhIUoZJTtkMR2FH8+pao0Qnz2cloirTxv5cgHfb4hU3obO
Ui9YPpKkuWXUls50u/eIr3/O/xLpzp6W/mlcQOxH0gOo0H5RUZmr5JgRZ7ykx8ly
NP/8vO8C1bXXUzXCvYAcd27eS6SOE0+KXvrvl0BQZ4Q=
base64_decode_len is 128
de=12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678