Closed PhillippOhlandt closed 4 years ago
@PhillippOhlandt It looks like you're actually passing {:ok, "..."}
instead of just "..."
as the second argument there.
Try using {:ok, data_string} = Poison.encode(data)
or data_string = Poison.encode!(data)
and let me know if things work as expected or not.
@potatosalad Uh, you are right. I simply didn't see that. Now it works.
iex(8)> signed = JOSE.JWK.sign(data_string, %{ "alg" => "RS256" }, rsa_private_jwk)
{%{alg: :jose_jws_alg_rsa_pkcs1_v1_5},
%{"payload" => "eyJjbGFpbXMiOnsiaWRfdG9rZW4iOnsib3BlbmJhbmtpbmdfaW50ZW50X2lkIjp7InZhbHVlIjoiaWQgaGVyZSIsImVzc2VudGlhbCI6dHJ1ZX19fX0",
"protected" => "eyJhbGciOiJSUzI1NiJ9",
"signature" => "dBPQvhT8fmGRUh2bngAyYbnoKWqCrXz7j891u-flOfvyqFbcMW99bFE-7NgtSuykfzjRZmWKD52OuigyXI7ToFxFhZwqcmzECEoEECqNHiGf4BF-MdUx4m8MSfFQ01U0T8-aqyg9MLxBwq72RC0toWeSlljukzEG_4o8pK64Hz3e_g6vwjeIAW74ROGClYHlQ20G0oeV1rkkom9VVZHcgd1eeGtqZr640SwAhP6vgIRtwRm9wSrS_PpRWRo8AyoDVC-lB2li_m7vaMrGzBfUgYb_qUGaqScU7l-Ur1w9x1iclZY3iraWopw7yfcx_gY7U4nC1_us1IQ383R0zvUntA"}}
I guess the "signature" is my JWT now, right? (Sorry, the whole thing with the banking spec just confuses me.)
EDIT: I should think before I post. The whole thing seems to be the JWT. I guess I have to concatenate them with a .
to build the JWT. Is there a helper function for that?
Is there a helper function for that?
Yes, JOSE.JWS.compact/1
.
Also, you might have a better experience overall using JOSE.JWT
(optionally with ojson
, but poison also works):
secret_jwk = JOSE.JWK.from("{\"d\":\"Ky7xJxzbqt7Sgpv9rHKJnegcazBv4Rpz6Z0Q4n7TrlKrdyFYQxGAbhQdNcIWn33_D97JwKtmXcQwYz2A8vXlZHbkwBhbBcSCFQ5YSQdU-KCAoSkj-oaLVlzSs6Gudqxwa3o59S6Y_sCz7v4-zAbf8MxqmKB1cBG7fmF3T8b8LTAAwtvm2UHtnH9dFgcOFGbDLAZnLa6atBT2f5kKJttYet40yPyilOIONZs714QkWhk6ZyzWYtE11zyIwZu4IUlE4JHyF41O1LrYZ5BxdxZBXTTSY0EOz8JM0tMUgr8BxnnI2fjZYwV1E097HFLNUYR-a6bWUngc24oL5NkE_xLHAQ\",\"dp\":\"yxMV-OPnEwEZOySOwJOaRKAQ-uYIe1P-hv3zoEGn-EgSzMYNpFH60O3Aqjn3DaIGch-NzykXk8yd1izQCK2u4nGLk_S89_W8Vcninj_satS-iaBlfNz5B0h14jwGfiqUyZYugnmPqh0zbgTetjpNq9UwcWmu7P2SQjSO5FVj81M\",\"dq\":\"HD_Hn1t44qEafLr9KAHeMIB3CAJOyRzgvM6gGLTkNRzOrhHINMkdJDxYHSTSya8F24aGfDnW6Y3JdFh8wU0pyhrQ5z-iK1XVvAbMn3GTiLDw9QDzlhsFEbHMB-Bou5iuLxue5OLAb4fhrlav04NgPjvy7x_dpDWGjpnJOWeyPAE\",\"e\":\"AQAB\",\"kty\":\"RSA\",\"n\":\"sOdk8QW1jengFToHHKWfKbqWqeQT3fws_6ninQHLiCaPug1eMcMvMv23YYFFL5mQZmDevTnhOxaY5-5mnLyzhCYrD6rrU8-biE_W5Zcv2GcSr1ijJqtQslQwA2YHwCqdZPNyBVJRLwqCH5c_X017LZyFmfTEg1TFh87u1XB-SmL8aaLiyl3H8fdYV3ws6AJIn9IyuKGxst6VCgRpoHw3Aif5BRY9bYYbHQpPXEkKZxNDZlZKPD59qvFfqZ3ciyqYWOdXXbHk9H4uo3h-buWLeb9W1GN0R31027gTaZ_dlkrQUIa4tIbMJA9U5kq4KkyFPdECAdF0CrbQm8WhNepXJw\",\"p\":\"1t78KQZNhi6ICa3IshBJs823ECTZICUjsYGUTxAumKbsfbt90TQYGYdDIkMJL6vmaJFA2vvKmqL1U9WWRfKIVb0gZbVmwX-A0HdVHyljMX-oCnolXDLtds_kNCJwotDCLHWpVOX1OlFFeFQBDel9oEfu_7k-JNgw5uLz9sat4ec\",\"q\":\"0sP1t1jWcZpDFZwIexNMius8ZmRz-c_KqFEL3wmz0WY7EjMChd4EHpYLAGCFyQdyjS8nt0Qr7mre9GYm_QZimgOVvkRayEbovTe9943Xux4f4b73z-4jzz0E8eg8gL2akrRmme2AxBbiVoKC3KeDE_ClZM2LiwznZ_7UQrVDuME\",\"qi\":\"R8bUn9ptKidLtMn8LtkibUOOTb0KPTnt9Ftz8t1h121X3qfO-pQWUcDB1gJNhb0kMsNVrZsl1xsIE-aCPPCIJ-WK9nklET-D7DIRYU_tkdmtaIIGNpWCid2qIZZdkb0pGZSIHUydiCvXwwqF_yxiZBGVA9N2gkfoRKA9Zmw3TYk\"}")
# The Open Banking docs mention using the "certificate id" as the key id,
# but I'm not sure how they're calculating that.
# Here I'm just using the JWK's thumbprint as the key id (or "kid").
jws = JOSE.JWS.from(%{
"alg" => "RS256",
"kid" => JOSE.JWK.thumbprint(secret_jwk),
"typ" => "JWT"
})
jwt = JOSE.JWT.from(%{
"claims" => %{
"id_token" => %{
"openbanking_intent_id" => %{
"value" => "id here",
"essential" => true
}
}
}
})
signed = JOSE.JWT.sign(secret_jwk, jws, jwt) |> JOSE.JWS.compact() |> elem(1)
# => "eyJhbGciOiJSUzI1NiIsImtpZCI6IkR0c05zLUdKQ0lwLXJTS3RnaUttazI1UnNOS0xNX25pQWttSThvNDV6dW8iLCJ0eXAiOiJKV1QifQ.eyJjbGFpbXMiOnsiaWRfdG9rZW4iOnsib3BlbmJhbmtpbmdfaW50ZW50X2lkIjp7ImVzc2VudGlhbCI6dHJ1ZSwidmFsdWUiOiJpZCBoZXJlIn19fX0.ftfY08cUPmpx4TBcEJ6MLbqZGgSfVPo7cqWBiGJCSrYCrZoLiABZ5xW9TtKlYdSwhYB-CnfhQgMhGBFs-ITKjrr1FfRYV8RvdpLdtCR_fk72YcPMN_5YZwqDXLtvFNBC56hKhv-UqUeCG3zygXfiqfQeBeXb0czAwHSx5Zw1F7FxLSYSSGyaQwG_gTcQm8XEpV-goEAfERdTY_SkW0xk-KqcHAIFyr5mMVxshRINp1wsTsunfpRcUyRye9FcyK0Nbr3Sn3o4gfCLvXzVcI366Hvdw_Qk9sZGpO7-WMnM2eEBws-QIYjxVZb_OWUeedEnVrkU5LePmeSlRoHmC831cw"
# Verification (only verifies signature, not any internal claims)
public_jwk = JOSE.JWK.to_public(secret_jwk)
{true, ^jwt, ^jws} = JOSE.JWT.verify_strict(public_jwk, ["RS256"], signed)
The JSON encoding and decoding is handled internally by whatever JOSE.json_module/0
returns:
iex> JOSE.json_module()
:jose_json_ojson
Wow, that looks like something that could work! Thank you. Just that I load my secret_jwk
from the pem file I generated (like in my example), right?
Yes, in my example I'm loading the same PEM file private key you posted originally.
I just converted it to JSON with JOSE.JWK.to_binary/1
.
Hey,
I got some problems signing my JWT.
Here is what I did:
I basically followed the example in the README.
I want to implement https://openbanking.atlassian.net/wiki/spaces/DZ/pages/7046134/Open+Banking+Security+Profile+-+Implementer+s+Draft+v1.1.0#OpenBankingSecurityProfile-Implementer'sDraftv1.1.0-JSONSecuritySuiteInformationv1.0 and have quite a lot of problems doing so. Maybe someone who is a bit deeper into this topic could help me out with this.
Thanks.