@@ -26,7 +26,22 @@ $ pip install cwt
2626
2727And then, you can use it as follows:
2828
29- ``` py
29+ ** COSE API**
30+
31+ ``` pycon
32+ >>> from cwt import COSE , COSEKey
33+ >>> ctx = COSE .new()
34+ >>> mac_key = COSEKey.generate_symmetric_key(alg = " HS256" , kid = " 01" )
35+ >>> encoded = ctx.encode_and_mac(b " Hello world!" , mac_key, unprotected = {" alg" : " HS256" })
36+ >>> encoded.hex()
37+ 'd18443a10105a1044230314c48656c6c6f20776f726c642158205d0b144add282ccaac32a02e0d5eec76928ccadf3623271eb48e9464e2ee03b2'
38+ >>> ctx.decode(encoded, mac_key)
39+ b'Hello world!'
40+ ```
41+
42+ ** CWT API**
43+
44+ ``` pycon
3045>>> import cwt
3146>>> from cwt import COSEKey
3247>>> key = COSEKey.generate_symmetric_key(alg = " HS256" , kid = " 01" )
@@ -37,7 +52,9 @@ And then, you can use it as follows:
3752{1: 'coaps://as.example', 2: 'dajiaji', 7: b'123', 4: 1620088759, 5: 1620085159, 6: 1620085159}
3853```
3954
40- See [ Documentation] ( https://python-cwt.readthedocs.io/en/stable/ ) for details.
55+ Various usage examples are shown in this README.
56+
57+ See [ Documentation] ( https://python-cwt.readthedocs.io/en/stable/ ) for the details of API specification.
4158
4259## Index
4360
@@ -89,10 +106,9 @@ pip install cwt
89106
90107## COSE Usage Examples
91108
92- Followings are typical and basic examples which create various types of COSE messages, verify and decode them.
109+ Followings are typical and basic examples which encode various types of COSE messages and decode them.
93110
94- See [ API Reference] ( https://python-cwt.readthedocs.io/en/stable/api.html#cwt.COSE ) and
95- [ COSE Usage Examples on document] ( https://python-cwt.readthedocs.io/en/stable/cose_usage.html ) for more details.
111+ See [ API Reference] ( https://python-cwt.readthedocs.io/en/stable/api.html#cwt.COSE ) .
96112
97113### COSE MAC0
98114
@@ -167,6 +183,7 @@ mac_key = COSEKey.generate_symmetric_key(alg="HS512", kid="01")
167183
168184# The sender side:
169185r = Recipient.new(unprotected = {" alg" : " direct" , " kid" : mac_key.kid})
186+ # r = Recipient.new(unprotected={1: -6, 4: mac_key.kid}) # is also acceptable.
170187
171188sender = COSE .new()
172189encoded = sender.encode_and_mac(b " Hello world!" , mac_key, recipients = [r])
@@ -192,12 +209,12 @@ r = Recipient.new(
192209 " alg" : " direct+HKDF-SHA-256" ,
193210 " salt" : " aabbccddeeffgghh" ,
194211 },
212+ context = {" alg" : " HS256" },
195213)
196- mac_key = r.encode(shared_key.to_bytes(), context = {" alg" : " HS256" })
197214sender = COSE .new(alg_auto_inclusion = True )
198215encoded = sender.encode_and_mac(
199216 b " Hello world!" ,
200- mac_key ,
217+ shared_key ,
201218 recipients = [r],
202219)
203220
@@ -213,19 +230,17 @@ The AES key wrap algorithm can be used to wrap a MAC key as follows:
213230``` py
214231from cwt import COSE , COSEKey, Recipient
215232
233+ # The sender side:
234+ mac_key = COSEKey.generate_symmetric_key(alg = " HS512" )
216235enc_key = COSEKey.from_jwk(
217236 {
218237 " kty" : " oct" ,
219238 " kid" : " 01" ,
220239 " alg" : " A128KW" ,
221240 " k" : " hJtXIZ2uSN5kbQfbtTNWbg" , # A shared wrapping key
222241 }
223- );
224-
225- # The sender side:
226- mac_key = COSEKey.generate_symmetric_key(alg = " HS512" )
242+ )
227243r = Recipient.new(unprotected = {" alg" : " A128KW" }, sender_key = enc_key)
228- r.encode(mac_key.to_bytes())
229244sender = COSE .new(alg_auto_inclusion = True )
230245encoded = sender.encode_and_mac(b " Hello world!" , mac_key, recipients = [r])
231246
@@ -255,10 +270,16 @@ pub_key = COSEKey.from_jwk(
255270 " y" : " HlLtdXARY_f55A3fnzQbPcm6hgr34Mp8p-nuzQCE0Zw" ,
256271 }
257272)
258- r = Recipient.new({" alg" : " ECDH-ES+HKDF-256" }, recipient_key = pub_key)
259- mac_key = r.encode(context = {" alg" : " HS256" })
273+ r = Recipient.new(
274+ unprotected = {" alg" : " ECDH-ES+HKDF-256" },
275+ recipient_key = pub_key,
276+ context = {" alg" : " HS256" },
277+ )
260278sender = COSE .new(alg_auto_inclusion = True )
261- encoded = sender.encode_and_mac(b " Hello world!" , mac_key, recipients = [r])
279+ encoded = sender.encode_and_mac(
280+ b " Hello world!" ,
281+ recipients = [r],
282+ )
262283
263284# The recipient side:
264285# The following key is the private key of the above pub_key.
@@ -286,9 +307,8 @@ assert b"Hello world!" == recipient.decode(encoded, priv_key, context={"alg": "H
286307``` py
287308from cwt import COSE , COSEKey, Recipient
288309
289- mac_key = COSEKey.generate_symmetric_key(alg = " HS256" )
290-
291310# The sender side:
311+ mac_key = COSEKey.generate_symmetric_key(alg = " HS256" )
292312pub_key = COSEKey.from_jwk(
293313 {
294314 " kty" : " EC" ,
@@ -299,8 +319,11 @@ pub_key = COSEKey.from_jwk(
299319 " y" : " HlLtdXARY_f55A3fnzQbPcm6hgr34Mp8p-nuzQCE0Zw" ,
300320 }
301321)
302- r = Recipient.new(unprotected = {" alg" : " ECDH-ES+A128KW" }, recipient_key = pub_key)
303- r.encode(mac_key.to_bytes(), context = {" alg" : " HS256" })
322+ r = Recipient.new(
323+ unprotected = {" alg" : " ECDH-ES+A128KW" },
324+ recipient_key = pub_key,
325+ context = {" alg" : " HS256" },
326+ )
304327sender = COSE .new(alg_auto_inclusion = True )
305328encoded = sender.encode_and_mac(
306329 b " Hello world!" ,
@@ -416,7 +439,7 @@ enc_key = COSEKey.generate_symmetric_key(alg="ChaCha20/Poly1305", kid="01")
416439# The sender side:
417440nonce = enc_key.generate_nonce()
418441r = Recipient.new(unprotected = {" alg" : " direct" , " kid" : enc_key.kid})
419- # r = Recipient.new(unprotected={1: -6, 4: enc_key.kid}) # is also acceptable
442+ # r = Recipient.new(unprotected={1: -6, 4: enc_key.kid}) # is also acceptable.
420443
421444sender = COSE .new()
422445encoded = sender.encode_and_encrypt(
@@ -446,12 +469,12 @@ r = Recipient.new(
446469 " alg" : " direct+HKDF-SHA-256" ,
447470 " salt" : " aabbccddeeffgghh" ,
448471 },
472+ context = {" alg" : " A256GCM" },
449473)
450- enc_key = r.encode(shared_key.to_bytes(), context = {" alg" : " A256GCM" })
451474sender = COSE .new(alg_auto_inclusion = True )
452475encoded = sender.encode_and_encrypt(
453476 b " Hello world!" ,
454- key = enc_key ,
477+ shared_key ,
455478 recipients = [r],
456479)
457480
@@ -483,7 +506,6 @@ r = Recipient.new(
483506 unprotected = {" alg" : " A128KW" },
484507 sender_key = wrapping_key,
485508)
486- r.encode(enc_key.to_bytes())
487509sender = COSE .new(alg_auto_inclusion = True )
488510encoded = sender.encode_and_encrypt(b " Hello world!" , key = enc_key, recipients = [r])
489511
@@ -520,12 +542,14 @@ pub_key = COSEKey.from_jwk(
520542 " y" : " HlLtdXARY_f55A3fnzQbPcm6hgr34Mp8p-nuzQCE0Zw" ,
521543 }
522544)
523- r = Recipient.new(unprotected = {" alg" : " ECDH-ES+HKDF-256" }, recipient_key = pub_key)
524- enc_key = r.encode(context = {" alg" : " A128GCM" })
545+ r = Recipient.new(
546+ unprotected = {" alg" : " ECDH-ES+HKDF-256" },
547+ recipient_key = pub_key,
548+ context = {" alg" : " A128GCM" },
549+ )
525550sender = COSE .new(alg_auto_inclusion = True )
526551encoded = sender.encode_and_encrypt(
527552 b " Hello world!" ,
528- key = enc_key,
529553 recipients = [r],
530554)
531555
@@ -572,8 +596,12 @@ s_priv_key = COSEKey.from_jwk(
572596 " d" : " Uqr4fay_qYQykwcNCB2efj_NFaQRRQ-6fHZm763jt5w" ,
573597 }
574598)
575- r = Recipient.new(unprotected = {" alg" : " ECDH-SS+A128KW" }, sender_key = s_priv_key, recipient_key = r_pub_key)
576- r.encode(enc_key.to_bytes(), context = {" alg" : " A128GCM" })
599+ r = Recipient.new(
600+ unprotected = {" alg" : " ECDH-SS+A128KW" },
601+ sender_key = s_priv_key,
602+ recipient_key = r_pub_key,
603+ context = {" alg" : " A128GCM" },
604+ )
577605sender = COSE .new(alg_auto_inclusion = True )
578606encoded = sender.encode_and_encrypt(
579607 b " Hello world!" ,
@@ -632,7 +660,6 @@ r = Recipient.new(
632660 },
633661 recipient_key = rpk,
634662)
635- r.encode(enc_key.to_bytes())
636663sender = COSE .new()
637664encoded = sender.encode_and_encrypt(
638665 b " This is the content." ,
@@ -729,14 +756,12 @@ assert b"Hello world!" == recipient.decode(encoded, pub_key)
729756
730757## CWT Usage Examples
731758
732- Followings are typical and basic examples which create various types of CWTs, verify and decode them.
759+ Followings are typical and basic examples which encode various types of CWTs, verify and decode them.
733760
734761[ CWT API] ( https://python-cwt.readthedocs.io/en/stable/api.html ) in the examples are built
735762on top of [ COSE API] ( https://python-cwt.readthedocs.io/en/stable/api.html#cwt.COSE ) .
736763
737- See [ API Reference] ( https://python-cwt.readthedocs.io/en/stable/api.html ) and
738- [ CWT Usage Examples on document] ( https://python-cwt.readthedocs.io/en/stable/cwt_usage.html )
739- for more details.
764+ See [ API Reference] ( https://python-cwt.readthedocs.io/en/stable/api.html ) .
740765
741766### MACed CWT
742767
@@ -748,7 +773,7 @@ from cwt import Claims, COSEKey
748773
749774try :
750775 key = COSEKey.generate_symmetric_key(alg = " HS256" , kid = " 01" )
751- token = cwt.encode( {" iss" : " coaps://as.example" , " sub" : " dajiaji" , " cti" : " 123" }, key)
776+ token = cwt.{" iss" : " coaps://as.example" , " sub" : " dajiaji" , " cti" : " 123" }, key)
752777 decoded = cwt.decode(token, key)
753778
754779 # If you want to treat the result like a JWT;
@@ -777,7 +802,7 @@ import cwt
777802from cwt import COSEKey
778803
779804key = COSEKey.generate_symmetric_key(alg = " HS256" , kid = " 01" )
780- token = cwt.encode( {1 : " coaps://as.example" , 2 : " dajiaji" , 7 : b " 123" }, key)
805+ token = cwt.{1 : " coaps://as.example" , 2 : " dajiaji" , 7 : b " 123" }, key)
781806decoded = cwt.decode(token, key)
782807```
783808
@@ -802,7 +827,7 @@ from cwt import COSEKey
802827# The sender side:
803828with open (" ./private_key.pem" ) as key_file:
804829 private_key = COSEKey.from_pem(key_file.read(), kid = " 01" )
805- token = cwt.encode(
830+ token = cwt.
806831 {" iss" : " coaps://as.example" , " sub" : " dajiaji" , " cti" : " 123" }, private_key
807832)
808833
@@ -828,7 +853,7 @@ private_key = COSEKey.from_jwk({
828853 " x" : " 2E6dX83gqD_D0eAmqnaHe1TC1xuld6iAKXfw2OVATr0" ,
829854 " d" : " L8JS08VsFZoZxGa9JvzYmCWOwg7zaKcei3KZmYsj7dc" ,
830855})
831- token = cwt.encode(
856+ token = cwt.
832857 {" iss" : " coaps://as.example" , " sub" : " dajiaji" , " cti" : " 123" }, private_key
833858)
834859
@@ -855,7 +880,7 @@ import cwt
855880from cwt import COSEKey
856881
857882enc_key = COSEKey.generate_symmetric_key(alg = " ChaCha20/Poly1305" , kid = " 01" )
858- token = cwt.encode( {" iss" : " coaps://as.example" , " sub" : " dajiaji" , " cti" : " 123" }, enc_key)
883+ token = cwt.{" iss" : " coaps://as.example" , " sub" : " dajiaji" , " cti" : " 123" }, enc_key)
859884decoded = cwt.decode(token, enc_key)
860885```
861886
@@ -876,12 +901,12 @@ enc_key = COSEKey.generate_symmetric_key(alg="ChaCha20/Poly1305", kid="enc-01")
876901# Creates a CWT with ES256 signing.
877902with open (" ./private_key.pem" ) as key_file:
878903 private_key = COSEKey.from_pem(key_file.read(), kid = " sig-01" )
879- token = cwt.encode(
904+ token = cwt.
880905 {" iss" : " coaps://as.example" , " sub" : " dajiaji" , " cti" : " 123" }, private_key
881906)
882907
883908# Encrypts the signed CWT.
884- nested = cwt.encode( token, enc_key)
909+ nested = cwt.token, enc_key)
885910
886911# Decrypts and verifies the nested CWT.
887912with open (" ./public_key.pem" ) as key_file:
@@ -891,7 +916,7 @@ decoded = cwt.decode(nested, [enc_key, public_key])
891916
892917### CWT with User Settings
893918
894- The ` cwt ` in ` cwt.encode( ) ` and ` cwt.decode() ` above is a global ` CWT ` class instance created
919+ The ` cwt ` in ` cwt.) ` and ` cwt.decode() ` above is a global ` CWT ` class instance created
895920with default settings in advance. The default settings are as follows:
896921- ` expires_in ` : ` 3600 ` seconds. This is the default lifetime in seconds of CWTs.
897922- ` leeway ` : ` 60 ` seconds. This is the default leeway in seconds for validating ` exp ` and ` nbf ` .
@@ -903,7 +928,7 @@ from cwt import COSEKey, CWT
903928
904929key = COSEKey.generate_symmetric_key(alg = " HS256" , kid = " 01" )
905930mycwt = CWT .new(expires_in = 3600 * 24 , leeway = 10 )
906- token = mycwt.encode( {" iss" : " coaps://as.example" , " sub" : " dajiaji" , " cti" : " 123" }, key)
931+ token = mycwt.{" iss" : " coaps://as.example" , " sub" : " dajiaji" , " cti" : " 123" }, key)
907932decoded = mycwt.decode(token, key)
908933```
909934
@@ -920,7 +945,7 @@ from cwt import COSEKey
920945# The sender side:
921946with open (" ./private_key.pem" ) as key_file:
922947 private_key = COSEKey.from_pem(key_file.read(), kid = " 01" )
923- token = cwt.encode(
948+ token = cwt.
924949 {
925950 1 : " coaps://as.example" , # iss
926951 2 : " dajiaji" , # sub
@@ -966,7 +991,7 @@ my_claim_names = {
966991}
967992
968993cwt.set_private_claim_names(my_claim_names)
969- token = cwt.encode(
994+ token = cwt.
970995 {
971996 " iss" : " coaps://as.example" ,
972997 " sub" : " dajiaji" ,
@@ -1010,7 +1035,7 @@ with open("./private_key_of_issuer.pem") as key_file:
10101035 private_key = COSEKey.from_pem(key_file.read(), kid = " issuer-01" )
10111036
10121037# Sets the PoP key to a CWT for the presenter.
1013- token = cwt.encode(
1038+ token = cwt.
10141039 {
10151040 " iss" : " coaps://as.example" ,
10161041 " sub" : " dajiaji" ,
@@ -1090,7 +1115,7 @@ from cwt import Claims, COSEKey
10901115with open (" ./private_key_of_cert.pem" )) as f:
10911116 private_key = COSEKey.from_pem(f.read(), kid = " 01" )
10921117
1093- token = cwt.encode(
1118+ token = cwt.
10941119 {" iss" : " coaps://as.example" , " sub" : " dajiaji" , " cti" : " 123" }, private_key
10951120)
10961121
0 commit comments