PEM格式的私钥有何特殊之处? [英] What is special for a private key to be PEM-formatted?

查看:558
本文介绍了PEM格式的私钥有何特殊之处?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过Python将 Google API与oAuth服务帐户一起使用 3.4.步骤之一是生成JSON网络令牌,我为此使用 PyJWT .

我这一代的代码如下:

# 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.

但是,私钥似乎已正确提取.

为什么这种格式不正确?

解决方案

检查了PyJWT源代码后,很明显,该库希望PEM数据为字符串类型,但是您要提供一个字节字符串(在您的b'...'字面意思的问题). 令人反感的功能是 prepare_key 可接受的字符串类型的定义. /p>

您必须将私钥数据解码为本机str类型:

private_key_bytes = OpenSSL.crypto.dump_privatekey(OpenSSL.crypto.FILETYPE_PEM, p12.get_privatekey())
private_key = private_key_bytes.decode('utf-8')

这似乎仅在Python 3中是必需的,但是上面的代码也应在Python 2中工作.

I am trying to use the Google API with a oAuth service account, with Python 3.4. One of the steps is to generate a JSON Web Token, for which I use PyJWT.

My code for the generation is the following:

# 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"})

The call to jwt.encode crashes with TypeError: Expecting a PEM-formatted key. The full traceback:

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.

The private key, however, seems to be extracted correctly.

Why isn't this format correct?

解决方案

Having examined the PyJWT source code, it is apparent that the library expects the PEM data to be a string type, but you are providing a bytestring (evident in your question by the b'...' literal). The offending function is prepare_key, along with the definition of acceptable string types.

You must decode the private key data into the native str type:

private_key_bytes = OpenSSL.crypto.dump_privatekey(OpenSSL.crypto.FILETYPE_PEM, p12.get_privatekey())
private_key = private_key_bytes.decode('utf-8')

This only seems to be required for Python 3, but the above code should work for Python 2 as well.

这篇关于PEM格式的私钥有何特殊之处?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆