Skip to content

Commit e518634

Browse files
committed
新增:abe核心代码
1 parent e84f6a5 commit e518634

File tree

11 files changed

+905
-1
lines changed

11 files changed

+905
-1
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
/CMakeSettings.json
33
.vs
44
out
5+
build

devapi/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,9 @@ add_library(devapi STATIC
3939
crud.cc
4040
${HEADERS}
4141
)
42+
add_subdirectory(abe)
4243

43-
target_link_libraries(devapi PUBLIC common)
44+
target_link_libraries(devapi PUBLIC common abe)
4445

4546
add_coverage(devapi)
4647

devapi/abe/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
add_library(abe STATIC
2+
base64.cc
3+
abe_crypto.cc
4+
rewrite.cc
5+
)
6+
target_include_directories(abe PUBLIC /usr/local/lib /usr/lib/x86_64-linux-gnu)
7+
target_link_libraries(abe PUBLIC mysqlclient crypto relic relic_ec openabe)

devapi/abe/abe_crypto.cc

Lines changed: 319 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,319 @@
1+
#include <fstream>
2+
#include <cassert>
3+
#include <iostream>
4+
#include <unistd.h>
5+
#include <openssl/sha.h>
6+
#include <openssl/rsa.h>
7+
#include <openssl/err.h>
8+
#include <openssl/pem.h>
9+
#include "openssl/crypto.h"
10+
#include "mysqlx/abe/abe_crypto.h"
11+
#include "mysqlx/abe/base64.h"
12+
13+
14+
bool abe_crypto::encrypt(string pt, string policy, string &ct){
15+
16+
InitializeOpenABE();
17+
OpenABECryptoContext cpabe("CP-ABE");
18+
cpabe.importPublicParams(mpk);
19+
cpabe.encrypt(policy.c_str(), pt, ct);
20+
ShutdownOpenABE();
21+
22+
// std::cout<<"encrypt succefully!"<<std::endl;
23+
return true;
24+
}
25+
26+
bool abe_crypto::decrypt(string ct, string &pt){
27+
28+
if(!check_abe_key()){
29+
return false;
30+
}
31+
32+
InitializeOpenABE();
33+
OpenABECryptoContext cpabe("CP-ABE");
34+
cpabe.importPublicParams(mpk);
35+
cpabe.importUserKey(user.user_id.c_str(), user.user_key);
36+
if(!cpabe.decrypt(user.user_id.c_str(), ct, pt)){
37+
pt = "can't decrypt.";
38+
}
39+
// std::cout << "Recovered message: " << pt << std::endl;
40+
ShutdownOpenABE();
41+
42+
return true;
43+
}
44+
45+
bool abe_crypto::check_abe_key(){
46+
if(user.user_key == ""){
47+
ABE_ERROR("there is no abe_key, please run:\n\tshow current_abe_key;\nto get from database");
48+
return false;
49+
}
50+
return true;
51+
}
52+
53+
54+
bool abe_crypto::init(string mpk_path, string key_path,
55+
string kms_cert_path, string db_cert_path,
56+
string rsa_sk_path){
57+
if(!(import_mpk(mpk_path)
58+
&& import_db_cert(db_cert_path) && import_kms_cert(kms_cert_path)
59+
&& import_sk(rsa_sk_path))){
60+
return false;
61+
}
62+
if(!import_user_key(key_path)){ //abe_user_key可以之后获取
63+
user.user_key = "";
64+
}
65+
return true;
66+
}
67+
68+
bool abe_crypto::import_mpk(string mpk_path){
69+
//读入mpk
70+
std::ifstream ifs_mpk(mpk_path, std::ios::in);
71+
if(!ifs_mpk){
72+
ABE_ERROR2("error opening security pameter (mpk) file.\nmpk_path=", mpk_path);
73+
return false;
74+
}
75+
ifs_mpk>>mpk;
76+
ifs_mpk.close();
77+
return true;
78+
}
79+
80+
bool abe_crypto::import_user_key(string key_path){
81+
//读入abe_user_key
82+
std::ifstream ifs_key(key_path, std::ios::in);
83+
if(!ifs_key){
84+
ABE_ERROR("there is no abe_key, please run:\n\tshow current_abe_key;\nto get from database");
85+
return false;
86+
}
87+
ifs_key>>user.user_key;
88+
ifs_key.close();
89+
return true;
90+
}
91+
92+
bool abe_crypto::save_user_key(string key_path, string key_str_b64){
93+
string pt;
94+
95+
//key_str为base64编码
96+
size_t key_str_b64_length = key_str_b64.length();
97+
char * key_str = (char*)malloc(base64_utils::b64_dec_len(key_str_b64_length));
98+
size_t key_str_length = base64_utils::b64_decode(key_str_b64.c_str(), key_str_b64_length, (char*)key_str);
99+
// base64_utils::b64_decode(key_str_b64.c_str(), key_str_b64_length, (char*)key_str);
100+
101+
string ct(key_str,key_str_length);
102+
if(!rsa_decrypt(ct, pt)){
103+
free(key_str);
104+
ABE_ERROR("failed to decrypt abe user key");
105+
return false;
106+
}
107+
free(key_str);
108+
109+
if(user.user_key != ""){
110+
string decide = "";
111+
std::cout << "You already have abe key, do you want to update it?(Y/n)";
112+
if(!std::getline(std::cin, decide) || (decide != "y" && decide != "Y" && decide != "")){
113+
return false;
114+
}
115+
}
116+
//写入abe_user_key
117+
std::ofstream ofs_key(key_path, std::ios::out);
118+
if(!ofs_key){
119+
ABE_ERROR2("error opening user key-file.\nkey_path=" , key_path);
120+
return false;
121+
}
122+
ofs_key << pt;
123+
user.user_key = pt;
124+
ofs_key.close();
125+
return true;
126+
}
127+
128+
bool abe_crypto::import_sk(string rsa_sk_path){
129+
// 导入rsa密钥文件并读取密钥
130+
FILE *hPriKeyFile = fopen(rsa_sk_path.c_str(), "rb");
131+
if (hPriKeyFile == NULL)
132+
{
133+
// assert(false);
134+
return false;
135+
}
136+
std::string strRet;
137+
RSA *pRSAPriKey = RSA_new();
138+
if (PEM_read_RSAPrivateKey(hPriKeyFile, &pRSAPriKey, 0, 0) == NULL)
139+
{ // 密钥读取失败
140+
// assert(false);
141+
RSA_free(pRSAPriKey);
142+
fclose(hPriKeyFile);
143+
return false;
144+
}
145+
sk = pRSAPriKey;
146+
fclose(hPriKeyFile);
147+
return true;
148+
}
149+
150+
RSA * abe_crypto::import_pk(const string cert_path, string &err_msg){
151+
RSA * pk;
152+
// 导入证书文件并读取公钥
153+
FILE *hPubKeyFile = fopen(cert_path.c_str(), "rb");
154+
if (hPubKeyFile == NULL)
155+
{
156+
err_msg = "failed to open cert file";
157+
return NULL;
158+
}
159+
X509 *cert = PEM_read_X509(hPubKeyFile, nullptr, nullptr, nullptr);
160+
if(cert == NULL){
161+
err_msg = "failed to read publib key from cert file";
162+
fclose(hPubKeyFile);
163+
return NULL;
164+
}
165+
fclose(hPubKeyFile);
166+
167+
EVP_PKEY *evp_key = X509_get_pubkey(cert);
168+
if(evp_key == NULL){
169+
err_msg = "failed to get publib key from cert file";
170+
X509_free(cert);
171+
return NULL;
172+
}
173+
X509_free(cert);
174+
175+
pk = EVP_PKEY_get1_RSA(evp_key);
176+
if(pk == NULL){
177+
err_msg = "failed to get rsa publib key from cert file";
178+
EVP_PKEY_free(evp_key);
179+
return NULL;
180+
}
181+
EVP_PKEY_free(evp_key);
182+
183+
return pk;
184+
}
185+
186+
bool abe_crypto::import_db_cert(string db_cert_path){
187+
string err_msg;
188+
RSA *pk = import_pk(db_cert_path, err_msg);
189+
if(pk == NULL){
190+
err_msg += ":" + db_cert_path;
191+
ABE_ERROR(err_msg);
192+
return false;
193+
}
194+
db_pk = pk;
195+
return true;
196+
}
197+
198+
bool abe_crypto::import_kms_cert(string kms_cert_path){
199+
string err_msg;
200+
RSA *pk = import_pk(kms_cert_path, err_msg);
201+
if(pk == NULL){
202+
err_msg += ":" + kms_cert_path;
203+
ABE_ERROR(err_msg);
204+
return false;
205+
}
206+
kms_pk = pk;
207+
return true;
208+
}
209+
210+
abe_crypto::~abe_crypto(){
211+
if(kms_pk!= NULL) RSA_free(kms_pk);
212+
if(db_pk!= NULL) RSA_free(db_pk);
213+
if(sk != NULL) RSA_free(sk);
214+
}
215+
216+
bool abe_crypto::verify_sig(RSA *pk, unsigned char * msg, size_t msg_length, unsigned char * sig, size_t sig_length){
217+
unsigned char digest[SHA512_DIGEST_LENGTH];
218+
// 对输入进行hash
219+
SHA512(msg, msg_length, digest);
220+
221+
// 对签名进行认证
222+
int ret = RSA_verify(NID_sha512, digest, SHA512_DIGEST_LENGTH, sig, sig_length, pk);
223+
if (ret != 1){
224+
ABE_ERROR("verify error");
225+
unsigned long ulErr = ERR_get_error();
226+
char szErrMsg[1024] = {0};
227+
ABE_ERROR2("error number:" , ulErr);
228+
ERR_error_string(ulErr, szErrMsg); // 格式:error:errId:库:函数:原因
229+
std::cout << szErrMsg << std::endl;
230+
return false;
231+
}
232+
return true;
233+
234+
}
235+
236+
bool abe_crypto::verify_db_sig(const string msg, const string sig_b64){
237+
//sig是base64编码,需要先解码
238+
size_t sig_b64_length = sig_b64.length();
239+
unsigned char * sig = (unsigned char*)malloc(base64_utils::b64_dec_len(sig_b64_length));
240+
size_t sig_length = base64_utils::b64_decode(sig_b64.c_str(), sig_b64_length, (char*)sig);
241+
242+
if(!verify_sig(db_pk, (unsigned char *)msg.c_str(), msg.length(), sig, sig_length)){
243+
free(sig);
244+
ABE_ERROR("db_sig: verify failed");
245+
return false;
246+
}
247+
ABE_LOG("db_sig: verify success");
248+
free(sig);
249+
return true;
250+
}
251+
252+
bool abe_crypto::verify_kms_sig(const string msg_b64, const string sig_b64){
253+
254+
//msg和sig都是base64编码,需要先解码
255+
size_t msg_b64_length = msg_b64.length();
256+
unsigned char * msg = (unsigned char*)malloc(base64_utils::b64_dec_len(msg_b64_length));
257+
size_t msg_length = base64_utils::b64_decode(msg_b64.c_str(), msg_b64_length, (char*)msg);
258+
259+
size_t sig_b64_length = sig_b64.length();
260+
unsigned char * sig = (unsigned char*)malloc(base64_utils::b64_dec_len(sig_b64_length));
261+
size_t sig_length = base64_utils::b64_decode(sig_b64.c_str(), sig_b64_length, (char*)sig);
262+
263+
if(!verify_sig(kms_pk, msg, msg_length, sig, sig_length)){
264+
free(msg);
265+
free(sig);
266+
ABE_ERROR("kms_sig: verify failed");
267+
return false;
268+
}
269+
270+
ABE_LOG("kms_sig: verify success");
271+
free(msg);
272+
free(sig);
273+
return true;
274+
}
275+
276+
//注意ct初始化时必须指定长度,否则ct.length会因为0x00而截断
277+
bool abe_crypto::rsa_decrypt(const string ct, string &pt){
278+
int nLen = RSA_size(sk);
279+
char *pDecode = new char[nLen + 1];
280+
bool flag = true;
281+
// 解密,不限长度,但为RSA_Decrypt_length的整数倍
282+
if (ct.length() < RSA_Decrypt_length + 1)
283+
{ // 一个分组的情况
284+
int ret = RSA_private_decrypt(ct.length(), (const unsigned char *)ct.c_str(),
285+
(unsigned char *)pDecode, sk, RSA_PKCS1_PADDING);
286+
if (ret >= 0)
287+
{ // 解密成功
288+
pt = std::string((char *)pDecode, ret);
289+
}
290+
else
291+
{ // 解密失败
292+
pt = "";
293+
flag = false;
294+
}
295+
}
296+
else
297+
{ // 多个分组
298+
for (int i = 0; i < (int)ct.length() / (int)RSA_Decrypt_length; i++)
299+
{
300+
std::string Data = ct.substr(i * RSA_Decrypt_length, RSA_Decrypt_length);
301+
int ret = RSA_private_decrypt(Data.length(), (const unsigned char *)Data.c_str(),
302+
(unsigned char *)pDecode, sk, RSA_PKCS1_PADDING);
303+
if (ret >= 0)
304+
{
305+
pt += std::string(pDecode, ret);
306+
}
307+
else
308+
{ // 解密失败
309+
pt = "";
310+
flag = false;
311+
break;
312+
}
313+
}
314+
}
315+
316+
delete[] pDecode;
317+
CRYPTO_cleanup_all_ex_data();
318+
return flag;
319+
}

0 commit comments

Comments
 (0)