2015-05-07 59 views
2

我想在Python 3.4中使用Google API with a oAuth service account。其中一個步驟是generate a JSON Web Token,爲此我使用PyJWT對於PEM格式的私鑰有什麼特別之處?

我對代碼如下:

# opening the certificate downloaded from the Google API console 
# it is password protected by the standard password ('notasecret') 
p12 = OpenSSL.crypto.load_pkcs12(open('certfromgoogle.p12', 'rb').read(), 'notasecret') 

# extracting the private key from the certificate and dumping it to a PEM 
# format (FILETYPE_PEM) 
private_key = OpenSSL.crypto.dump_privatekey(OpenSSL.crypto.FILETYPE_PEM, p12.get_privatekey()) 

# at that stage, private_key contains the private key as 
# b'-----BEGIN PRIVATE KEY-----\nMIICdg(...)FIyw==\n-----END PRIVATE KEY-----\n' 

# trying to get the JWT 
encoded = jwt.encode(claim, private_key, algorithm='RS256', headers={"alg": "RS256", "typ": "JWT"}) 

的調用jwt.encode崩潰,並TypeError: Expecting a PEM-formatted key。完整的回溯:

Traceback (most recent call last): 
    File "C:/Users/w_000/PycharmProjects/syncmagazines/testcrypto.py", line 20, in <module> 
    encoded = jwt.encode(claim, private_key, algorithm='RS256', headers={"alg": "RS256", "typ": "JWT"}) 
    File "C:\Python34\lib\site-packages\jwt\api.py", line 118, in encode 
    key = alg_obj.prepare_key(key) 
    File "C:\Python34\lib\site-packages\jwt\algorithms.py", line 170, in prepare_key 
    raise TypeError('Expecting a PEM-formatted key.') 
TypeError: Expecting a PEM-formatted key. 

然而,私鑰似乎被正確提取。

爲什麼這種格式不正確?

+0

*「對jwt.encode的調用崩潰...」* - 私鑰是否被加密? – jww

+0

您使用的是哪個版本的Python?你可以包括追溯? – frasertweedale

+0

@jww:我更新了我的代碼,以明確它是否可用於明文 – WoJ

回答

1

審查了PyJWT源代碼,很明顯,該庫的預期,PEM數據是一個字符串類型,但你(由b'...'字面明顯,在你的問題)提供一個字節串。 違規功能是prepare_key,連同acceptable string types的定義。

必須私鑰數據解碼成原生str類型:

​​

這似乎只需要爲Python 3,但上面的代碼應爲Python 2正常工作。

+0

謝謝,這正是問題所在。在'private_key = ...'行添加'.decode('utf-8')'後,我得到了一個正確的JWT。 – WoJ

0

對於PEM格式的私鑰有什麼特別之處?

PEM是一種演示編碼。它有熟悉的-----BEGIN XXX----------END XXX-----

我認爲BEGIN PRIVATE KEY是一個PKCS#8私鑰。也許圖書館想要一個PKCS#1私鑰,其密鑰爲BEGIN RSA PRIVATE KEYBEGIN RSA PRIVATE KEY也被稱爲傳統密鑰編碼(而不是PKCS#8)。

您應該檢查相關文檔並以正確的格式提供密鑰。

要從傳統密鑰轉換爲PKCS#8密鑰,請參閱pkcs(1)的OpenSSL手冊頁。 -topk8是有趣的。另請參閱How to convert PKCS#8-formatted PEM private key to the tranditional format?

要從PKCS#8密鑰轉換爲傳統密鑰,請參閱OpenSSL手冊頁獲取rsa(1)。另請參閱Convert PEM traditional private key to PKCS8 private key?

+0

錯誤指出所需的格式是PEM,這是我轉儲(爲清晰起見註釋代碼) – WoJ

+0

@WoJ - 您提供了PKCS#8 PEM編碼密鑰。庫是否需要PKCS#1 PEM編碼密鑰? PKCS#1 PEM在OpenSSL中被認爲是* Traditional *鍵。 – jww