在坑里面折騰了兩天時間,搞的是心力憔悴。最后問題解決后才發(fā)現(xiàn)氓皱,在這個坑里折騰這么久當真不應該。分享下心路歷程勃刨,后來者引以為戒波材。
問題描述
RSA算法最典型的使用方式是在客戶端生成公鑰私鑰對,將公鑰發(fā)送到服務器身隐。然后服務器與客戶端間的通信數(shù)據(jù)就可以通過這一對公鑰私鑰加解密了廷区。這個典型流程也可以參考我這篇文章。
提交公鑰數(shù)據(jù)最常見的方式是將公鑰信息轉化成一串字符串后提交贾铝。還有一種方式是同時提取出公鑰中的modules與exponent數(shù)據(jù)上傳隙轻,而這個坑就出現(xiàn)在后一種方式上。
struct rsa_st {
/*
* The first parameter is used to pickup errors where this is passed
* instead of aEVP_PKEY, it is set to 0
*/
int pad;
long version;
const RSA_METHOD *meth;
/* functional reference if 'meth' is ENGINE-provided */
ENGINE *engine;
BIGNUM *n;
BIGNUM *e;
BIGNUM *d;
BIGNUM *p;
BIGNUM *q;
BIGNUM *dmp1;
BIGNUM *dmq1;
BIGNUM *iqmp;
/* be careful using this if the RSA structure is shared */
CRYPTO_EX_DATA ex_data;
int references;
int flags;
/* Used to cache montgomery values */
BN_MONT_CTX *_method_mod_n;
BN_MONT_CTX *_method_mod_p;
BN_MONT_CTX *_method_mod_q;
/*
* all BIGNUM values are actually in the following data, if it is not
* NULL
*/
char *bignum_data;
BN_BLINDING *blinding;
BN_BLINDING *mt_blinding;
};
在一次破解實踐中垢揩,我注意到自己demo中用openssl生成的公鑰信息結構中n玖绿、e的值與動態(tài)調試app中的數(shù)據(jù)恰好互換了位置:即app中n與demo中的e一致,app中e與demo中n一致叁巨。給人的感覺好像是這個app重寫了openssl里的RSA對象結構斑匪,導致了n、e的位置與公開的頭文件不一致俘种。當時我也有想到可能是openssl版本不一致導致,但偷懶的情緒使我完全沒有在這條路上深入下去绝淡。
我按照第一種想法簡單的將n宙刘、e的值手動互換并上報到服務器,然后服務器也成功接受并返回了加密的數(shù)據(jù)牢酵,只是無法用私鑰成功解密悬包。如此這樣成功入坑,并在坑里反復折騰馍乙,想盡各種辦法布近,就是沒有任何效果垫释。
問題解決
最終無奈之下決定下載個低版本試試,在openssl官網(wǎng)下載了一個1.0.0版本撑瞧。編譯后引入工程棵譬,測試發(fā)現(xiàn)n、e值不在像以前那樣錯位了预伺,服務器返回數(shù)據(jù)也成功解密了订咸。天終于又亮了,心情瞬間陽光普照了酬诀。脏嚷。。瞒御。
問題反思
這個問題的本質是目標app使用的openssl版本與我使用的版本不一致父叙,而這兩個版本在RSA對象結構上的細微差別恰好導致了問題的出現(xiàn)。
回頭反思整個入坑過程肴裙,最主要的原因還是自己對openssl中RSA結構不熟悉導致趾唱。如果能夠對RSA結構體內的每個成員變量的含義了如指掌、對RSA的算法原理洞若觀火践宴,相信應該一眼就能看出問題的本質來鲸匿。看來后面要補一補基本算法方面的缺了阻肩,有人能給推薦本常用加密算法的書籍么骇陈?