2015-05-07 42 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