android jni c++ aes cbc 128加密解密
最近公司要数据加密,要求用c++进行解密,android还是很容易反编译,而so文件反编译难一点,在网上找到了开源的代码从openssl中抽出了AES ecb cbc的代码,可是加密完发现数据是十六进制的,同样解密的数据也是十六进制的,没办法只能转换成字符串,在网上找了一些转换的代码
加密解密c++代码
#include <sstream> extern "C"{ #include "aes.h" } //把字符串转成十六进制字符串 std::string char2hex(std::string s) { std::string ret; for (unsigned i = 0; i != s.size(); ++i) { char hex[5]; sprintf(hex, "%.2x", (unsigned char)s[i]); ret += hex; } return ret; } //把十六进制字符串转成字符串 std::string hex2char(std::string s) { std::string ret; int length = (int) s.length(); for (int i = 0; i <length ; i+=2) { std::string buf = "0x"+s.substr(i,2); unsigned int value; sscanf(buf.c_str(), "%x", &value); ret += ((char)value); } return ret; } int hexCharToInt(char c){ if(c >= '0' && c <= '9') return (c - '0'); if(c >= 'A' && c <= 'F') return (c - 'A'+10); if(c >= 'a' && c <= 'f') return (c - 'a'+10); return 0; } //十六进制字符串转成十六进制数组 char * hexstringToBytes(std::string s){ int sz = (int) s.length(); char *ret = new char[sz/2]; for (int i = 0; i < sz; i+=2) { ret[i/2] = (char)((hexCharToInt(s.at(i)) << 4)|hexCharToInt(s.at(i+1))); } return ret; } //十六进制数组转成十六进制字符串 std::string bytestohexstring(char *bytes,int bytelength){ std::string str(""); std::string str2("0123456789abcdef"); for (int i = 0; i < bytelength; ++i) { int b; b = 0x0f&(bytes[i]>>4); char s1 = str2.at(b); str.append(1,str2.at(b)); b = 0x0f&bytes[i]; str.append(1,str2.at(b)); // char s2 = str2.at(b); } return str; } //加密 std::string EncodeAES(const unsigned char *master_key,std::string data,const unsigned char *iv){ AES_KEY key; AES_set_encrypt_key(master_key, 128, &key); unsigned char ivc[AES_BLOCK_SIZE]; std::string data_bak = data.c_str(); unsigned int data_length = (unsigned int) data_bak.length(); int padding = 0; if (data_bak.length() % AES_BLOCK_SIZE >= 0) { padding = (int) (AES_BLOCK_SIZE - data_bak.length() % AES_BLOCK_SIZE); } data_length += padding; while (padding > 0) { data_bak += '\0'; padding--; } memcpy( ivc, iv, AES_BLOCK_SIZE*sizeof(char)); std::string encryhex; for(unsigned int i = 0; i < data_length/AES_BLOCK_SIZE; i++) { std::string str16 = data_bak.substr(i*AES_BLOCK_SIZE, AES_BLOCK_SIZE); unsigned char out[AES_BLOCK_SIZE]; memset(out, 0, AES_BLOCK_SIZE); AES_cbc_encrypt((const unsigned char *) str16.c_str(), out, 16, &key, ivc, AES_ENCRYPT); encryhex += bytestohexstring((char *) out, AES_BLOCK_SIZE); } return encryhex; } //解密 std::string DecodeAES(const unsigned char *master_key,std::string data,const unsigned char *iv){ AES_KEY key; AES_set_decrypt_key(master_key, 128, &key); unsigned char ivc[AES_BLOCK_SIZE]; memcpy( ivc, iv, AES_BLOCK_SIZE*sizeof(char)); std::string ret; for(unsigned int i = 0; i < data.length()/(AES_BLOCK_SIZE*2); i++) { std::string str16 = data.substr(i*AES_BLOCK_SIZE*2, AES_BLOCK_SIZE*2); unsigned char out[AES_BLOCK_SIZE]; memset(out, 0, AES_BLOCK_SIZE); char *buf = hexstringToBytes(str16); AES_cbc_encrypt((const unsigned char *)buf , out, AES_BLOCK_SIZE, &key, ivc, AES_DECRYPT); delete(buf); ret += hex2char(bytestohexstring((char *) out, AES_BLOCK_SIZE)); } return ret; } extern "C" JNIEXPORT jstring JNICALL Java_com_example_aes_MainActivity_encryptString(JNIEnv *env, jclass type, jstring str_) { const char *str = env->GetStringUTFChars(str_, 0); // TODO const unsigned char *master_key = (const unsigned char *) "1234567890abcdef"; const unsigned char *iv = (const unsigned char *) "90abcdef12345678"; std::string h = EncodeAES(master_key, str, iv); env->ReleaseStringUTFChars(str_, str); return env->NewStringUTF(h.c_str()); }extern "C" JNIEXPORT jstring JNICALL Java_com_example_aes_MainActivity_decryptString(JNIEnv *env, jclass type, jstring str_) { const char *str = env->GetStringUTFChars(str_, 0); // TODO const unsigned char *master_key = (const unsigned char *) "1234567890abcdef"; const unsigned char *iv = (const unsigned char *) "90abcdef12345678"; std::string s = DecodeAES(master_key,str,iv); env->ReleaseStringUTFChars(str_, str); return env->NewStringUTF(s.c_str()); }
java代码
public native static String encryptString(String str); public native static String decryptString(String str);
String s = encryptString("abcdefg"); Log.d(TAG,"encrypt:"+s); s = decryptString(s); Log.d(TAG,"decrypt:"+s);
效果