接口測試之加密測試


一、對稱加密

對稱加密算法是共享密鑰加密算法,在加密解密過程中,使用的密鑰只有一個。發送和接收雙方事先都知道加密的密鑰,均使用這個密鑰對數據進行加密和解密。

數據加密:在對稱加密算法中,數據發送方將明文 (原始數據) 和 加密密鑰一起經過加密處理,生成復雜的密文進行發送。

數據解密:數據接收方收到密文后,使用加密的密鑰及相同算法的逆算法對加密的密文進行解密,將使其恢復成可讀明文。

二、非對稱加密

非對稱加密算法,有兩個密鑰,一個稱為公開密鑰 (publickey),另一個稱為 私有密鑰 (private key),加密和解密使用的是兩個不同的密鑰,所以這種算法稱為非對稱加密算法。

如果使用公鑰對數據進行加密,只有用對應的私鑰才能進行解密。

如果使用私鑰對數據進行加密,只有用對應的公鑰才能進行解密。

三、常見加密處理方式

根據上述常見的加密算法,測試人員在測試不同的加密接口可采用下述的方法處理加密接口

摘要算法(MD5.SHA1 ):造接口數據前調用MD5,SHA1進行編碼,服務端對比編碼后的字符串是否一致

對稱加密算法(AES,DES ):造接口數據前從開發獲取對稱公鑰,基於對稱公鑰可以加密請求數據,解密響應報文

非對稱加密算法(RSA):造接口數據前從開發獲取公鑰私鑰去加密解密接口數據

用戶認證:一般的接口測試工具都會提供一個User Auth/Authorization的選項

1、OAuth 2.0認證

在對應的工具上,你可以選取對應的用戶認證選項,如果用Python如何實現用戶認證。

  • 首先安裝Requests庫,Requests庫的get()和post()方法均提供有auth參數,用於設置用戶簽名。
  • 假定我們有一個接口為添加一個新的公告,接口需要認證:auth=("username","password"),nid 或 name兩個參數二選一
  • 偽代碼:
def test_get_notice_list_nid_sucess(self):
    auth_user = ('admin' , 'admin123456')
    r = requests.get(self.base_url, auth = auth_user, params = {'nid' : 1})
    result = r.json()
    self.assertEqual(result['status'], 200)

2、數字簽名

在使用 HTTP/SOAP 協議傳輸數據的時候,簽名作為其中一個參數,可以起到關鍵作用:

先來一個簡單的,通過客戶的密鑰,服務端的密鑰匹配;

這個很有好理解,例如一個接口傳參為:

http://127.0.0.1:8000/api/?a=1&b=2

假設簽名的密鑰為:@signpassword

加上簽名之后的接口參數為:

http://127.0.0.1:8000/sign/?a=1&b=2&sign=@signpassword

但是,這樣的sign 參數明文傳輸是不安全的,一般會選擇一些加密算法,比如MD5 算法(MD5算法是不可逆向的),比如MD5代碼如下:

import hashlib  
md5 = hashlib.md5()
sign_str = "@signpassword"
sign_bytes_utf8 = sign_str.encode()
md5.update(sign_bytes_utf8)
sign_md5 = md5.hexdigest()
print(sign_md5)

執行后得到:6648e929329e53e7a91c50ae685a88b5

此時帶簽名的接口為:

http://127.0.0.1:8000/sign/?a=1&b=2&sign=6648e929329e53e7a91c50ae685a88b5

所以,當服務器接收到請求后,同樣需要對“signpassword”進行 MD5 加密,然后,比對與調用者傳來的 sign 加密串是否一致,從而來鑒別調用者是否有權限使用該接口。

接着,我們來理解一個復雜一點的:把sign參數傳遞為api key(申請獲取)+ timestramp(時間戳)同樣需要用代碼來實現,原理和上面這個一致的。(偽代碼)

def setUp(self):   
    self.base_url = "http://127.0.0.1:8000/api/sec_add_notice/"
    # app_key
    self.api_key = "&APIkey"
    # 當前時間
    now_time = time()
    self.client_time = str(now_time).split('.')[0]
    # sign
    md5 = hashlib.md5()
    sign_str = self.client_time + self.api_key
    sign_bytes_utf8 = sign_str.encode(encoding="utf-8")
    md5.update(sign_bytes_utf8)
    self.sign_md5 = md5.hexdigest()

3、AES加解密的過程

通常接口會使用更復雜一點的方式來進行加密的操作,常見的是AES的使用,放一張圖讓大家感受一下AES加解密的過程:

Python里面有一個很好的黑魔法,叫PyCrypto庫,支持常見的 DES、AES 加密以及 MD5、SHA 各種 HASH 運算。

官方網站下載最新版本:

https://www.dlitz.net/software/pycrypto/

另外,也可以在 PyPi 倉庫中下載安裝:

https://pypi.python.org/pypi/pycrypto

對於AES的加密來說,看一下用了PyCrypto庫的結果

加密:

from Crypto.Cipher import AES
obj = AES.new('This is a key123', AES.MODE_CBC, 'This is an IV456')
message = "The answer is no"
ciphertext = obj.encrypt(message)
print(ciphertext)

程序運行后的結果為:

b'\xd6\x83\x8dd!VT\x92\xaa`A\x05\xe0\x9b\x8b\xf1'

AES加密里面有兩個關鍵,一個是key(必須為16,24,32位),一個是VI(必須為16位)

解密:解謎者必須要同時知道key和VI才可以解密

obj2 = AES.new('This is a key123', AES.MODE_CBC, 'This is an IV456')
s = obj2.decrypt(ciphertext)
print(s)

由Crypto庫的作者已停止維護,現推薦安裝:

 pip install pycrytodome

pycryptodome官方文檔:

https://www.pycryptodome.org/en/latest/

四、參考

https://github.com/yuxuan6699/Lot_API_Test


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM