1. 程式人生 > >Python rsa公私鑰生成 rsa公鑰加密(分段加密)私鑰加簽實戰

Python rsa公私鑰生成 rsa公鑰加密(分段加密)私鑰加簽實戰

you port pen man length comment 數據加密 自己 keygen

一般現在的SAAS服務提供現在的sdk或api對接服務都涉及到一個身份驗證和數據加密的問題。一般現在普遍的做法就是配置使用非對稱加密的方式來解決這個問題,你持有SAAS公司的公鑰,SAAS公司持有你的公鑰,你們就可以進行加密和簽名的驗證了。

先來看下兩種在linux或者mac下面生成key pair的方法:

使用openssl 生成一把2048bit長度的鑰匙對,首先我們生成一把.pem格式的私鑰:

openssl genrsa -out private_key.pem 2048

然後通過這把私鑰生成.pem格式的公鑰:

openssl rsa -in private_key.pem -pubout -out public_key.pem

生成出來的格式是pkcs#1.5格式的,可以直接被下面類似這種語句直接讀取 rsa.PublicKey.load_pkcs1_openssl_pem()對於python的rsa庫來說比較方便。

同樣我們也可以使用ssh-keygen來生成:

ssh-keygen -t rsa -b 2048 -C "[email protected]"

最後-C 參數是給這把鑰匙的公鑰添加一個comment。-t指定算法,-b指定長度。這種生成方法會讓你輸入一個密碼,這個密碼會對生成的private_key進行加密。

會長這個樣子開頭:

-----BEGIN RSA PRIVATE KEY-----
Proc
-Type: 4,ENCRYPTED DEK-Info: DES-CBC,84E01D31C0A59D1F

如果你想使用這把鑰匙進行加解密簽名轉成上面格式的鑰匙的話。需要使用:

openssl rsa -in <Encrypted key filename>  -out < desired output file name>

可以去掉密碼,得到私鑰。然後再使用這把私鑰生成一個公鑰,向上面一樣操作就可以了。直接使用生成pair的公鑰應該是不行的,格式不一樣並不是pkcs#1.5。

下面開始介紹加解密和加簽驗簽:

其實在此之前,有個概念非常容易被混淆。就是同樣使用非對稱加密原理的數據加密和數據加簽。

加密和加簽完全不是同樣一件事情。

加密使用的是公鑰對數據進行加密,而且當你使用一把1024bit的rsa公鑰的時候,你一次只能加密最多117byte的數據,如果數據量超過這個數,可能會涉及到對數據進行分段加密的問題。而且現在rsa 1024bit長度的鑰匙已經被證明了不夠安全,應該盡量使用2048bit長度的鑰匙。2048bit長度的鑰匙一次可以加密245byte長度的數據。這個計算方法是 2048bit/8 = 256byte - 11byte = 245byte長數據。就是鑰匙長度減去11byte得到的自己最大能一次加密多長的數據。如果超過了就會報錯,所以很多平臺要求對數據用公鑰進行加密,就可能涉及到分段加密的問題。

而加簽是使用自己的私鑰對需要加簽的字符串進行簽名。而對方需要拿著你給的公鑰來驗證這個數據是不是由你發出的,需要使用公鑰對數據進行驗簽。如果成功驗簽才能說明你是你。

下面展示使用python對數據進行分段加密的過程,這裏我們假設自己使用一把1024bit的公鑰進行加密:

def rsa_encrypt(biz_content, public_key):
    _p = rsa.PublicKey.load_pkcs1_openssl_pem(public_key)
    biz_content = biz_content.encode(utf-8)
    # 1024bit key
    default_encrypt_length = 117
    len_content = len(biz_content)
    if len_content < default_encrypt_length:
        return base64.b64encode(rsa.encrypt(biz_content, _p))
    offset = 0
    params_lst = []
    while len_content - offset > 0:
        if len_content - offset > default_encrypt_length:
            params_lst.append(rsa.encrypt(biz_content[offset:offset+default_encrypt_length], _p))
        else:
            params_lst.append(rsa.encrypt(biz_content[offset:], _p))
        offset += default_encrypt_length
    target = ‘‘.join(params_lst)
    return base64.b64encode(target)

最後一般需要使用base64算法將二進制流轉成字符串方便進行放入需要的參數裏面進行傳遞。解密同理可以使用rsa庫的此方法

rsa.decrypt(data, private_key)

進行分段解密之後把數據拼起來。

下面繼續展示對數據進行加簽的過程:

def rsa_signature(data, private_key):
    _pri = rsa.PrivateKey._load_pkcs1_pem(private_key)
    signature = rsa.sign(data, _pri, SHA-1)
    return base64.b64encode(signature)

驗簽使用:

def rsa_verify(signature, message, public_key):
    _pub = rsa.PublicKey.load_pkcs1_openssl_pem(public_key)
    signature = base64.b64decode(signature)
    return rsa.verify(message, signature, _pub)

以上

Reference:

https://stuvel.eu/python-rsa-doc/usage.html#signing-and-verification Python-RSA 3.4.2 documentation

https://support.citrix.com/article/CTX122930#Decrypting%20the%20Private%20Key%20from%20the%20Command%20Line%20Interface How to Decrypt an RSA Private Key Using OpenSSL on NetScaler

https://segmentfault.com/a/1190000009396950?_ea=2278883 Python的RSA加密和PBE加密

https://stackoverflow.com/questions/1011572/convert-pem-key-to-ssh-rsa-format Convert pem key to ssh-rsa format

Python rsa公私鑰生成 rsa公鑰加密(分段加密)私鑰加簽實戰