私钥是PEM格式的特殊之处是什么?

时间:2015-05-07 13:07:58

标签: python openssl public-key-encryption jwt

我正在尝试使用Python 3.4中的Google API with a oAuth service account。其中一个步骤是generate a JSON Web Token,我使用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.

然而,私钥似乎被正确提取。

为什么这种格式不正确?

2 个答案:

答案 0 :(得分:1)

在检查了PyJWT源代码后,很明显库希望PEM数据是一个字符串类型,但是你提供了一个字节串(在str文字的问题中很明显)。 违规函数为prepare_key,以及acceptable string types的定义。

您必须将私钥数据解码为本机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.

答案 1 :(得分:0)

  

PEM格式的私钥有什么特别之处?

PEM是一种演示编码。它有熟悉的-----BEGIN XXX----------END XXX-----

我认为 BEGIN PRIVATE KEY 是PKCS#8私钥。也许图书馆想要一个带有 BEGIN RSA PRIVATE KEY 的PKCS#1私钥。 BEGIN 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密钥转换为传统密钥,请参阅rsa(1)的OpenSSL手册页。另请参阅Convert PEM traditional private key to PKCS8 private key?

相关问题