Skip to content

Commit

Permalink
Merge pull request walt-id#607 from walt-id/fix/key-deserialization
Browse files Browse the repository at this point in the history
Fix key deserialization
  • Loading branch information
mikeplotean authored Jul 12, 2024
2 parents 32be86b + 7431f1a commit e0eb64b
Show file tree
Hide file tree
Showing 18 changed files with 172 additions and 89 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package id.walt.crypto.keys
import id.walt.crypto.keys.jwk.JWKKey
import id.walt.crypto.keys.oci.OCIKeyRestApi
import id.walt.crypto.keys.tse.TSEKey
import id.walt.crypto.utils.JsonUtils.toJsonElement
import io.github.oshai.kotlinlogging.KotlinLogging
import kotlinx.serialization.json.*
import kotlinx.serialization.serializer
Expand Down Expand Up @@ -50,17 +49,13 @@ object KeyManager {
return function.invoke(generationRequest)
}

fun resolveSerializedKey(jsonString: String): Key = resolveSerializedKey(json = Json.parseToJsonElement(jsonString).jsonObject)
// TODO: return Result<..>
fun resolveSerializedKey(json: JsonObject): Key {
val type = getRegisteredKeyType(json["type"]?.jsonPrimitive?.content ?: error("No type in serialized key"))

val fields = json.filterKeys { it != "type" }
//jwkKey is a stringified json
.mapValues { if (it.value is JsonObject) it.value.toString().toJsonElement() else it.value }

return Json.decodeFromJsonElement(serializer(type), JsonObject(fields)) as Key
}

suspend fun resolveSerializedKey(jsonString: String): Key =
resolveSerializedKey(json = Json.parseToJsonElement(jsonString).jsonObject)

// TODO: return Result<..>
suspend fun resolveSerializedKey(json: JsonObject): Key = json["type"]?.jsonPrimitive?.content?.let {
val type = getRegisteredKeyType(it)
val fields = json.filterKeys { it != "type" }.mapValues { it.value }
Json.decodeFromJsonElement(serializer(type), JsonObject(fields)) as Key
}?.apply { init() } ?: error("No type in serialized key")
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,13 @@ package id.walt.crypto.keys.jwk
import id.walt.crypto.keys.JwkKeyMeta
import id.walt.crypto.keys.Key
import id.walt.crypto.keys.KeyType
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.KSerializer
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encodeToString
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.json.*

expect class JWKKey(jwk: String?) : Key {
override val keyType: KeyType
Expand Down Expand Up @@ -71,3 +76,12 @@ expect class JWKKey(jwk: String?) : Key {
}

}

object JWKKeyJsonFieldSerializer : KSerializer<String?> {
override val descriptor: SerialDescriptor = JsonElement.serializer().descriptor
override fun deserialize(decoder: Decoder): String =
Json.encodeToString(decoder.decodeSerializableValue(JsonElement.serializer()))

override fun serialize(encoder: Encoder, value: String?) = encoder.encodeSerializableValue(JsonElement.serializer(),
value?.let { Json.decodeFromString<JsonElement>(it) } ?: JsonNull)
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import kotlin.js.json
@Serializable
@SerialName("jwk")
actual class JWKKey actual constructor(
@Serializable(with = JWKKeyJsonFieldSerializer::class)
var jwk: String?,
) : Key() {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import id.walt.crypto.keys.KeyManager
import id.walt.crypto.keys.KeySerialization
import id.walt.crypto.keys.KeyType
import id.walt.crypto.keys.jwk.JWKKey
Expand Down Expand Up @@ -41,19 +42,15 @@ class JWKKeyAndDidManagementTest {
assertEquals("jwk", decoded["type"]!!.jsonPrimitive.content)

println("Parsing JWK...")
val jwk = decoded["jwk"]!!.jsonPrimitive.content
val jwk = decoded["jwk"]!!.jsonObject
println("JWK is: $jwk")

println("Parsing JWK...")
val jwkObj = Json.parseToJsonElement(jwk).jsonObject
println("Parsed as: $jwkObj")

println("Getting kty, d, crv, kid, x...")
val kty = jwkObj["kty"].toString().removeSurrounding("\"")
val d = jwkObj["d"].toString().removeSurrounding("\"")
val crv = jwkObj["crv"].toString().removeSurrounding("\"")
val kid = jwkObj["kid"].toString().removeSurrounding("\"")
val x = jwkObj["x"].toString().removeSurrounding("\"")
val kty = jwk["kty"].toString().removeSurrounding("\"")
val d = jwk["d"].toString().removeSurrounding("\"")
val crv = jwk["crv"].toString().removeSurrounding("\"")
val kid = jwk["kid"].toString().removeSurrounding("\"")
val x = jwk["x"].toString().removeSurrounding("\"")

println("Checking kty, d, crv, kid, x...")
assertEquals(kty, getKeyTypeMap(it))
Expand Down Expand Up @@ -85,7 +82,7 @@ class JWKKeyAndDidManagementTest {
val testObjJson = Json.encodeToString(testObj)

// sign using newly generated key
val key = KeySerialization.deserializeKey(serializedKey).getOrThrow()
val key = KeyManager.resolveSerializedKey(serializedKey)
val signature = key.signJws(testObjJson.encodeToByteArray())

// verify the signature using public key
Expand All @@ -100,28 +97,28 @@ class JWKKeyAndDidManagementTest {
val testObjJson = Json.encodeToString(testObj)

// sign using newly generated key
val key = KeySerialization.deserializeKey(serializedKey).getOrThrow()
val key = KeyManager.resolveSerializedKey(serializedKey)
val signature = key.signRaw(testObjJson.encodeToByteArray())

assertNotNull(signature)
}

private suspend fun exportJwk(serializedKey: String) {
val decoded = Json.decodeFromString<JsonObject>(serializedKey)
val jwk = decoded["jwk"]!!.jsonPrimitive.content
val jwk = decoded["jwk"]!!.jsonObject

val key = KeySerialization.deserializeKey(serializedKey).getOrThrow()
val key = KeyManager.resolveSerializedKey(serializedKey)
val export = key.exportJWK()

assertEquals(jwk, export)
assertEquals(Json.encodeToString(jwk), export)
}

private suspend fun exportJson(serializedKey: String) {
val decoded = Json.decodeFromString<JsonObject>(serializedKey)
val jwk = decoded["jwk"]!!.jsonPrimitive.content
val jwk = decoded["jwk"]!!.jsonObject

val key = KeySerialization.deserializeKey(serializedKey).getOrThrow()
val key = KeyManager.resolveSerializedKey(serializedKey)
val export = key.exportJWKObject()
assertEquals(jwk, export.toString())
assertEquals(jwk, export)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ private val log = KotlinLogging.logger { }
@SerialName("jwk")
actual class JWKKey actual constructor(
@Suppress("CanBeParameter", "RedundantSuppression")
@Serializable(with = JWKKeyJsonFieldSerializer::class)
var jwk: String?
) : Key() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,13 @@ class JWKKeyAndDidManagementTest {

assertEquals("jwk", decoded["type"]!!.jsonPrimitive.content)

val jwk = decoded["jwk"]!!.jsonPrimitive.content
val jwkObj = Json.parseToJsonElement(jwk).jsonObject
val jwk = decoded["jwk"]!!.jsonObject

val kty = jwkObj["kty"].toString().removeSurrounding("\"")
val d = jwkObj["d"].toString().removeSurrounding("\"")
val crv = jwkObj["crv"].toString().removeSurrounding("\"")
val kid = jwkObj["kid"].toString().removeSurrounding("\"")
val x = jwkObj["x"].toString().removeSurrounding("\"")
val kty = jwk["kty"].toString().removeSurrounding("\"")
val d = jwk["d"].toString().removeSurrounding("\"")
val crv = jwk["crv"].toString().removeSurrounding("\"")
val kid = jwk["kid"].toString().removeSurrounding("\"")
val x = jwk["x"].toString().removeSurrounding("\"")

assertEquals(kty, getKeyTypeMap(it))
assertNotNull(d)
Expand Down Expand Up @@ -91,20 +90,20 @@ class JWKKeyAndDidManagementTest {

private suspend fun exportJwk(serializedKey: String) {
val decoded = Json.decodeFromString<JsonObject>(serializedKey)
val jwk = decoded["jwk"]!!.jsonPrimitive.content
val jwk = decoded["jwk"]!!.jsonObject

val key = KeyManager.resolveSerializedKey(serializedKey)
val export = key.exportJWK()

assertEquals(jwk, export)
assertEquals(Json.encodeToString(jwk), export)
}

private suspend fun exportJson(serializedKey: String) {
val decoded = Json.decodeFromString<JsonObject>(serializedKey)
val jwk = decoded["jwk"]!!.jsonPrimitive.content
val jwk = decoded["jwk"]!!.jsonObject

val key = KeyManager.resolveSerializedKey(serializedKey)
val export = key.exportJWKObject()
assertEquals(jwk, export.toString())
assertEquals(jwk, export)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import id.walt.crypto.keys.tse.TSEKey
import kotlinx.coroutines.test.runTest
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.Arguments
Expand All @@ -32,7 +33,7 @@ class KeySerializationTests {
val decoded = Json.decodeFromString<JsonObject>(serialized)
// then
assertEquals(type, decoded["type"]!!.jsonPrimitive.content)
assertEquals(keyFile.replace("\\s".toRegex(), ""), decoded["jwk"]!!.jsonPrimitive.content)
assertEquals(Json.decodeFromString(keyFile), decoded["jwk"]!!.jsonObject)
}

@ParameterizedTest
Expand Down
52 changes: 27 additions & 25 deletions waltid-libraries/waltid-crypto/src/jvmTest/kotlin/TestJvm.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.JsonPrimitive
import org.junit.jupiter.api.condition.EnabledIf
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.ValueSource
import kotlin.reflect.KClass
import kotlin.system.measureTimeMillis
import kotlin.test.*
Expand Down Expand Up @@ -53,31 +55,29 @@ class TestJvm {
}
}

@Test
fun testJWKKeySerialization() = runTest {
val jwkKey = JWKKey.generate(KeyType.Ed25519)
val jwkKeySerialized = KeySerialization.serializeKey(jwkKey)

val jsons = listOf(
jwkKeySerialized to JWKKey::class,
)

jsons.forEach {
check(it)
}
@ParameterizedTest
@ValueSource(
strings = [
"""{"type":"jwk","jwk":{"kty":"OKP","d":"mZVIizeqW7CbSidx5YetFD9hWqFkBZgwnsjt6Hcjxf4","crv":"Ed25519","kid":"m2Y_qWPRlvD5J8cDCNlCiJTa1gM1bcukNZWXSQ6ioVM","x":"0guspTLB3IM9f9kgT-061K-4NslAgAj1BoCmBE7zZ58"}}""",
]
)
fun testJWKKeySerialization(json: String) = runTest {
check(json to JWKKey::class)
}

@Test
@EnabledIf("isVaultAvailable")
fun testTseKeySerialization() = runTest {
val jsons = listOf(
"""{"type":"tse","server":"http://127.0.0.1:8200/v1/transit","accessKey":"dev-only-token","id":"k-307668075","_publicKey":[-41,-105,-126,77,-74,88,-28,123,93,-81,105,-13,-93,-111,27,81,-90,-1,86,59,68,105,-108,118,-68,121,18,-114,71,-69,-106,-109],"_keyType":"Ed25519"}""" to TSEKey::class,
@ParameterizedTest
@ValueSource(
strings = [
"""{"type":"tse","server":"http://127.0.0.1:8200/v1/transit","accessKey":"dev-only-token","id":"k-307668075","_publicKey":[-41,-105,-126,77,-74,88,-28,123,93,-81,105,-13,-93,-111,27,81,-90,-1,86,59,68,105,-108,118,-68,121,18,-114,71,-69,-106,-109],"_keyType":"Ed25519"}""",
"""{"type":"tse","server":"http://127.0.0.1:8200/v1/transit","auth":{"accessKey":"dev-only-token"},"id":"k1870739605","_publicKey":[24,100,-34,34,57,75,-79,106,107,18,70,61,-58,-52,-28,64,-44,69,-63,86,-67,2,28,80,-44,41,-14,112,8,-110,97,13],"_keyType":"Ed25519"}""",
"""{"type":"tse","server":"http://127.0.0.1:8200/v1/transit","auth":{"username":"myuser","password":"mypassword"},"id":"k1870739605","_publicKey":[24,100,-34,34,57,75,-79,106,107,18,70,61,-58,-52,-28,64,-44,69,-63,86,-67,2,28,80,-44,41,-14,112,8,-110,97,13],"_keyType":"Ed25519"}""",
"""{"type":"tse","server":"http://127.0.0.1:8200/v1/transit","auth":{"roleId":"2d2713db-593b-cc85-dff1-bd6793d47a4d","secretId":"09096426-05c6-a816-7a67-798eac0002e2"},"id":"k-1695742643","_publicKey":[113,63,23,-127,11,124,-37,-113,24,-53,68,101,83,-15,-21,62,-85,-47,50,-35,-94,-21,-39,5,126,82,24,-64,-85,-85,48,-65],"_keyType":"Ed25519"}""",
//"""{"type":"tse","server":"http://127.0.0.1:8200/v1/transit","accessKey":"dev-only-token","id":"k-307668075"}""" to TSEKey::class // TODO: cannot access key information in TSE when pre-generated (ID will ofc not be found)
)

jsons.forEach {
check(it)
}
]
)
fun testTseKeySerialization(json: String) = runTest {
check(json to TSEKey::class)
}

private val testObj = JsonObject(mapOf("value1" to JsonPrimitive("123456789")))
Expand Down Expand Up @@ -204,8 +204,10 @@ class TestJvm {
}
}

private fun isVaultAvailable() = runCatching {
runBlocking { HttpClient().get("http://127.0.0.1:8200") }.status == HttpStatusCode.OK
}.fold(onSuccess = { it }, onFailure = { false })

companion object {
@JvmStatic
fun isVaultAvailable() = runCatching {
runBlocking { HttpClient().get("http://127.0.0.1:8200") }.status == HttpStatusCode.OK
}.fold(onSuccess = { it }, onFailure = { false })
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
{
"type": "jwk",
"jwk": "{\"kty\":\"OKP\",\"d\":\"H-PBqzXk0Dd2k0pPnFW_4gdqRgZtbmckixYbaZN8-bg\",\"use\":\"sig\",\"crv\":\"Ed25519\",\"kid\":\"DJ-kT9JRDYwlJfYjhmJgNwIcuaU6RcSuR8eHIwbsnHQ\",\"x\":\"51sbDqo0X6YccLaxupF-QCR2Oz853AVGIwbXBOU77rU\",\"alg\":\"EdDSA\"}"
}
"jwk":
{
"kty": "OKP",
"d": "H-PBqzXk0Dd2k0pPnFW_4gdqRgZtbmckixYbaZN8-bg",
"use": "sig",
"crv": "Ed25519",
"kid": "DJ-kT9JRDYwlJfYjhmJgNwIcuaU6RcSuR8eHIwbsnHQ",
"x": "51sbDqo0X6YccLaxupF-QCR2Oz853AVGIwbXBOU77rU",
"alg": "EdDSA"
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
{
"type": "jwk",
"jwk": "{\"kty\":\"OKP\",\"use\":\"sig\",\"crv\":\"Ed25519\",\"kid\":\"DJ-kT9JRDYwlJfYjhmJgNwIcuaU6RcSuR8eHIwbsnHQ\",\"x\":\"51sbDqo0X6YccLaxupF-QCR2Oz853AVGIwbXBOU77rU\",\"alg\":\"EdDSA\"}"
}
"jwk":
{
"kty": "OKP",
"use": "sig",
"crv": "Ed25519",
"kid": "DJ-kT9JRDYwlJfYjhmJgNwIcuaU6RcSuR8eHIwbsnHQ",
"x": "51sbDqo0X6YccLaxupF-QCR2Oz853AVGIwbXBOU77rU",
"alg": "EdDSA"
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,16 @@
{
"type": "jwk",
"jwk": "{\"p\":\"0bNpJzzOOgzpqaWkb-5PuUgY9AedUsnze24AtukXaN9VY7e5BLYcbE11RGeyj8kkhpotvZQ6WrYEfvSkfxBvoVc1q86FXiqlpwmUL-_jO4BbgESOK9eaWP1iWmWNrZpqwdnIeF3VZHfCIoFxRV_Tb_Sp8UNSueFgCH6IVJlfwSE\",\"kty\":\"RSA\",\"q\":\"zsTarRYo9lLE8XvzpGzpjtrOHsnLuk2n5GXP6M2X89BL8yc8_5Fp99m_Em9vGAOhZBK9ActZuZEGSVVhfV1ImGw17tLyQZSCAvSzQpZSYpT9EDeZgn_oSorfUgMKppm1X4rl5Yz7lMR1khljdKt_X6gFA6ADL2h_ARK1bBRjr08\",\"d\":\"hndR21ddUYqRi9JfkDcSSzSwUX8R5jwjBaaCqLoKQX3J6VR7eHBv889VooXplheh_UaSeorkLb9Atd7ruF-EmKmuk1S28gr79-hiWa3H7MvIm647vGz0Z9VbhxQpDm9vLVtILbyYh1DVyRzHjOm9n4UyNmQfqolMjzF81_p6DUfpkMcDBJSlsTmRKMWPG0u8mFm8aB9ZftbryPO36QOny7g4_M8SZG1yxGTbypjyDTP9WqMmHpaC-66gLszjyxwEbVh69m-HsDEs7Qg9oMVG2FiwtDSXIApwfLk2v2Yk4-TeAD49rZzw-QcJ0yqPeVdq8cgyFOhwX-cPtQIm8X7AgQ\",\"e\":\"AQAB\",\"kid\":\"288WlRQvku-zrHFmvcAW86jnTF3qsMoEUKEbteI2K4A\",\"qi\":\"aJsDBhxQFDbpQr20TjgxImwBslVP9xIauy3ncCmjHix6Fc1l51gL71V1OWGnXaStGfoWy0gKkUnJuU3_X_xA_QwzAXPJYa-juRlD8BxTf7rmR_HC-XiVdyNnkU3afHtK4nShS2EuN2EXOrYDrbQoA13_a6Itk_55vDpJ3jciwS8\",\"dp\":\"lOfqTmN-KXiL39xwdM7rq6zHk1lo3KXtEIOfXEMOTXjxQJrwdaj_a-Rg1g8wm6uAFVicDFeaTFmdvazothWsvwuXYAWJbMGp2YASyytz1wehcea8ceNqhbB_y6L7RQA2uKp2EQrIgcwMfcYe8d1G3eQFXP2qW7XvJHj9Q92ZQiE\",\"dq\":\"E7TDOpfQE5nT10f-8n7Gy6yi1GBbIEhiZewmIoPlpYEGnAfzUlAjj1GbWkBwkBNYgFcg2FjvFjZyKO8QOYh4cL5vbXGBUSq8MVfs9b2p4Gdervr9kGhsVR5jJkfP7gzcMlzkiDoliAopQmFVDzuBCjbTM4M-inglEo8b508SKRU\",\"n\":\"qV-fGqTo8r6L52sIJpt44bxLkODaF0_wvIL_eYYDL55H-Ap-b1q4pd4YyZb7pARor_1mob6sMRnnAr5htmO1XucmKBEiNY-12zza0q9smjLm3-eNqq-8PgsEqBz4lU1YIBeQzsCR0NTa3J3OHfr-bADVystQeonSPoRLqSoO78oAtonQWLX1MUfS9778-ECcxlM21-JaUjqMD0nQR6wl8L6oWGcR7PjcjPQAyuS_ASTy7MO0SqunpkGzj_H7uFbK9Np_dLIOr9ZqrkCSdioA_PgDyk36E8ayuMnN1HDy4ak_Q7yEX4R_C75T0JxuuYio06hugwyREgOQNID-DVUoLw\"}"
}
"jwk":
{
"p": "0bNpJzzOOgzpqaWkb-5PuUgY9AedUsnze24AtukXaN9VY7e5BLYcbE11RGeyj8kkhpotvZQ6WrYEfvSkfxBvoVc1q86FXiqlpwmUL-_jO4BbgESOK9eaWP1iWmWNrZpqwdnIeF3VZHfCIoFxRV_Tb_Sp8UNSueFgCH6IVJlfwSE",
"kty": "RSA",
"q": "zsTarRYo9lLE8XvzpGzpjtrOHsnLuk2n5GXP6M2X89BL8yc8_5Fp99m_Em9vGAOhZBK9ActZuZEGSVVhfV1ImGw17tLyQZSCAvSzQpZSYpT9EDeZgn_oSorfUgMKppm1X4rl5Yz7lMR1khljdKt_X6gFA6ADL2h_ARK1bBRjr08",
"d": "hndR21ddUYqRi9JfkDcSSzSwUX8R5jwjBaaCqLoKQX3J6VR7eHBv889VooXplheh_UaSeorkLb9Atd7ruF-EmKmuk1S28gr79-hiWa3H7MvIm647vGz0Z9VbhxQpDm9vLVtILbyYh1DVyRzHjOm9n4UyNmQfqolMjzF81_p6DUfpkMcDBJSlsTmRKMWPG0u8mFm8aB9ZftbryPO36QOny7g4_M8SZG1yxGTbypjyDTP9WqMmHpaC-66gLszjyxwEbVh69m-HsDEs7Qg9oMVG2FiwtDSXIApwfLk2v2Yk4-TeAD49rZzw-QcJ0yqPeVdq8cgyFOhwX-cPtQIm8X7AgQ",
"e": "AQAB",
"kid": "288WlRQvku-zrHFmvcAW86jnTF3qsMoEUKEbteI2K4A",
"qi": "aJsDBhxQFDbpQr20TjgxImwBslVP9xIauy3ncCmjHix6Fc1l51gL71V1OWGnXaStGfoWy0gKkUnJuU3_X_xA_QwzAXPJYa-juRlD8BxTf7rmR_HC-XiVdyNnkU3afHtK4nShS2EuN2EXOrYDrbQoA13_a6Itk_55vDpJ3jciwS8",
"dp": "lOfqTmN-KXiL39xwdM7rq6zHk1lo3KXtEIOfXEMOTXjxQJrwdaj_a-Rg1g8wm6uAFVicDFeaTFmdvazothWsvwuXYAWJbMGp2YASyytz1wehcea8ceNqhbB_y6L7RQA2uKp2EQrIgcwMfcYe8d1G3eQFXP2qW7XvJHj9Q92ZQiE",
"dq": "E7TDOpfQE5nT10f-8n7Gy6yi1GBbIEhiZewmIoPlpYEGnAfzUlAjj1GbWkBwkBNYgFcg2FjvFjZyKO8QOYh4cL5vbXGBUSq8MVfs9b2p4Gdervr9kGhsVR5jJkfP7gzcMlzkiDoliAopQmFVDzuBCjbTM4M-inglEo8b508SKRU",
"n": "qV-fGqTo8r6L52sIJpt44bxLkODaF0_wvIL_eYYDL55H-Ap-b1q4pd4YyZb7pARor_1mob6sMRnnAr5htmO1XucmKBEiNY-12zza0q9smjLm3-eNqq-8PgsEqBz4lU1YIBeQzsCR0NTa3J3OHfr-bADVystQeonSPoRLqSoO78oAtonQWLX1MUfS9778-ECcxlM21-JaUjqMD0nQR6wl8L6oWGcR7PjcjPQAyuS_ASTy7MO0SqunpkGzj_H7uFbK9Np_dLIOr9ZqrkCSdioA_PgDyk36E8ayuMnN1HDy4ak_Q7yEX4R_C75T0JxuuYio06hugwyREgOQNID-DVUoLw"
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
{
"type": "jwk",
"jwk": "{\"kty\":\"RSA\",\"e\":\"AQAB\",\"kid\":\"288WlRQvku-zrHFmvcAW86jnTF3qsMoEUKEbteI2K4A\",\"n\":\"qV-fGqTo8r6L52sIJpt44bxLkODaF0_wvIL_eYYDL55H-Ap-b1q4pd4YyZb7pARor_1mob6sMRnnAr5htmO1XucmKBEiNY-12zza0q9smjLm3-eNqq-8PgsEqBz4lU1YIBeQzsCR0NTa3J3OHfr-bADVystQeonSPoRLqSoO78oAtonQWLX1MUfS9778-ECcxlM21-JaUjqMD0nQR6wl8L6oWGcR7PjcjPQAyuS_ASTy7MO0SqunpkGzj_H7uFbK9Np_dLIOr9ZqrkCSdioA_PgDyk36E8ayuMnN1HDy4ak_Q7yEX4R_C75T0JxuuYio06hugwyREgOQNID-DVUoLw\"}"
}
"jwk":
{
"kty": "RSA",
"e": "AQAB",
"kid": "288WlRQvku-zrHFmvcAW86jnTF3qsMoEUKEbteI2K4A",
"n": "qV-fGqTo8r6L52sIJpt44bxLkODaF0_wvIL_eYYDL55H-Ap-b1q4pd4YyZb7pARor_1mob6sMRnnAr5htmO1XucmKBEiNY-12zza0q9smjLm3-eNqq-8PgsEqBz4lU1YIBeQzsCR0NTa3J3OHfr-bADVystQeonSPoRLqSoO78oAtonQWLX1MUfS9778-ECcxlM21-JaUjqMD0nQR6wl8L6oWGcR7PjcjPQAyuS_ASTy7MO0SqunpkGzj_H7uFbK9Np_dLIOr9ZqrkCSdioA_PgDyk36E8ayuMnN1HDy4ak_Q7yEX4R_C75T0JxuuYio06hugwyREgOQNID-DVUoLw"
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
{
"type": "jwk",
"jwk": "{\"kty\":\"EC\",\"d\":\"ZVnHT7nY4zWiu5tF8l-ycWCCHB645Lc9MhXxUAQqZU0\",\"use\":\"sig\",\"crv\":\"secp256k1\",\"kid\":\"PIv-EHegS0qL__8D4t36kULI8vzBsH4yBshhmY036yA\",\"x\":\"IjAomwz3PFqdqjHR5e22P6tfd_VPqEjAPZ3d-ydEZAo\",\"y\":\"ckpj6l9glLUqXgfRBrMRe3gzmb9m_WS3TU5ociCK1uM\",\"alg\":\"ES256K\"}"
}
"jwk":
{
"kty": "EC",
"d": "ZVnHT7nY4zWiu5tF8l-ycWCCHB645Lc9MhXxUAQqZU0",
"use": "sig",
"crv": "secp256k1",
"kid": "PIv-EHegS0qL__8D4t36kULI8vzBsH4yBshhmY036yA",
"x": "IjAomwz3PFqdqjHR5e22P6tfd_VPqEjAPZ3d-ydEZAo",
"y": "ckpj6l9glLUqXgfRBrMRe3gzmb9m_WS3TU5ociCK1uM",
"alg": "ES256K"
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
{
"type": "jwk",
"jwk": "{\"kty\":\"EC\",\"use\":\"sig\",\"crv\":\"secp256k1\",\"kid\":\"PIv-EHegS0qL__8D4t36kULI8vzBsH4yBshhmY036yA\",\"x\":\"IjAomwz3PFqdqjHR5e22P6tfd_VPqEjAPZ3d-ydEZAo\",\"y\":\"ckpj6l9glLUqXgfRBrMRe3gzmb9m_WS3TU5ociCK1uM\",\"alg\":\"ES256K\"}"
}
"jwk":
{
"kty": "EC",
"use": "sig",
"crv": "secp256k1",
"kid": "PIv-EHegS0qL__8D4t36kULI8vzBsH4yBshhmY036yA",
"x": "IjAomwz3PFqdqjHR5e22P6tfd_VPqEjAPZ3d-ydEZAo",
"y": "ckpj6l9glLUqXgfRBrMRe3gzmb9m_WS3TU5ociCK1uM",
"alg": "ES256K"
}
}
Loading

0 comments on commit e0eb64b

Please sign in to comment.