JWT шифрует полезную нагрузку в python? (JWE)

Согласно RFC 7516 должна быть возможность зашифровать полезную нагрузку / заявку, называемую JWE.

Существуют ли какие-либо библиотеки Python, которые поддерживают это?

Я проверил PyJWT, python-jose и jwcrypto, но у них просто есть примеры для подписи с HS256 (JWS).

Извините, если это совершенно очевидно, но когда дело доходит до криптовалют, я очень осторожен.

3 ответа

Решение

Библиотеки Jose и jwcrypto могут выполнять JWE.

Для Хосе:

claims = {
'iss': 'http://www.example.com',
'sub': 42,
}
pubKey = {'k':\
           '-----BEGIN PUBLIC KEY-----\n\
-----END PUBLIC KEY-----'
    }
# decrypt on the other end using the private key
privKey = {'k': 
    '-----BEGIN RSA PRIVATE KEY-----\n'+\
'-----END RSA PRIVATE KEY-----'
}

encJwt = jose.encrypt(claims, pubKey)
serJwt = jose.serialize_compact(encJwt)
decJwt = jose.decrypt(jose.deserialize_compact(serJwt), privKey)

Для jwcrypto:

# algorithm to use
eprot = {'alg': "RSA-OAEP", 'enc': "A128CBC-HS256"}
stringPayload = u'attack at dawn'
E = jwe.JWE(stringPayload, json_encode(eprot))
E.add_recipient(pubKey)
encrypted_token = E.serialize(compact=True)
E = jwe.JWE()
E.deserialize(encrypted_token, key=privKey)
decrypted_payload = E.payload

Я могу добавить новую библиотеку к предложенным выше библиотекам с именемjwskate, как инициалы «JSON Web Signing, Keys, Algorithms, Tokens and Encryption». Отказ от ответственности: я являюсь автором этой библиотеки. Я написал это, потому что меня не устраивали API из предыдущих библиотек, которые, на мой взгляд, недостаточно Pythonic.

Вот пример использования для кодирования/декодирования JWE, в данном конкретном случае с использованиемECDH-ES+A256KWиA128CBC-HS256, но, очевидно, вы можете использовать любой поддерживаемый алгоритм управления ключами и шифрования:

      from jwskate import JweCompact, Jwk

plaintext = b"this is an example plaintext"

# I'll use this specific Elliptic Curve private key:
key = Jwk(
    {'kid': '8-nLgBsa-vXI_geoGt061_ZiVZ8BB-hYBDSoOQj9QgI',
     'alg': 'ECDH-ES+A256KW',
     'crv': 'P-256',
     'd': '39QMopTVL1u267FOx4ayvsueDU317vHaq_z-PU_NioA',
     'kty': 'EC',
     'x': 'f_VRZlIk1Qd2eNGFVas9sNXx9wd43L8VymknAyP5Ntk',
     'y': 'NmsfCs5VVOk6FEE31aaN9jB8rlfz1MWolBC3af_8DGs'}
)


# alternatively, you can generate one like this:
random_key = Jwk.generate_for_alg("ECDH-ES+A256KW").with_kid_thumbprint()

# sign your JWE
jwe = JweCompact.encrypt(plaintext, jwk=key.public_jwk(), enc="A128CBC-HS256")
print(jwe)
# it will look like: 
# eyJlcGsiOnsia3R5IjoiRUMiLCJjcnYiOiJQLTI1NiIsIngiOiItVnNfYkdSNTdUUVY4MHNnUENwcWZhVjNmWXR4dWdTWmJRM1FLeTJEVDdNIiwieSI6IjBtc0pZSUFfMC1OY2lfM0plOWZLSml3RU1ZdGRBaE9kZDZhdkp5THd0dzQifSwiYWxnIjoiRUNESC1FUytBMjU2S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2Iiwia2lkIjoiOC1uTGdCc2EtdlhJX2dlb0d0MDYxX1ppVlo4QkItaFlCRFNvT1FqOVFnSSJ9.nnOEhmdonA19LRvyKSrL7f8aEb2vVwE7EU-zO91fyTUls4otMVppYg.h8h7Mxz4irvckPnknsnM0g.sRQJJq-RmiF7GeqvL8EpWTstS-daLbfgGnOPybWeOj8.z3heCfTiI0cjw8GaV0qcHw


# as recipient, you can decrypt your JWE like this:
jwe = JweCompact("""eyJlcGsiOnsia3R5IjoiRUMiLCJjcnYiOiJQLTI1NiIsIngiOiJkSllwMHNTZUVhMnhiMkc4M2Jnam
1VNnp4OEFxTkZRVmlJclJXUnlJYURzIiwieSI6InJXcEZ0OENESGNkQXFoMVR2eG9BZTFCT3FfZ2I3RzJya0hVd0hhNldfV0kif
SwiYWxnIjoiRUNESC1FUytBMjU2S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2Iiwia2lkIjoiOC1uTGdCc2EtdlhJX2dlb0d0MDYx
X1ppVlo4QkItaFlCRFNvT1FqOVFnSSJ9.Nt89wpmYDZmbmjQCEZnZOygTOP5x2s7trvzLFehw1I_lMzTU-qlrcg.SQgJPG_WNUn
F13XnCJMAtw.wWwu_VUG7LPbsnWFTv-rAyiG84RW4tszR2fQ-AQaLBI.Onf3K4MSKhXaUrS8NpMDIA""")
assert jwe.decrypt(key) == plaintext

https://jwcrypto.readthedocs.io/en/latest/jwk.html

from jwcrypto import jwk
_k = jwk.JWK.generate(kty='RSA', size=2048)
_text = _k.export()

import json
# loading the key back
_import_key_dict = json.loads(_text)
key = jwk.JWK(**json.loads(_import_key_dict))

Другие вопросы по тегам